Leaked source code of windows server 2003
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.

2437 lines
59 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. mars.c
  5. Abstract:
  6. Routines that build and parse MARS packets.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. arvindm 12-12-96 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. #define _FILENUMBER 'TKPM'
  15. #ifdef IPMCAST
  16. PUCHAR
  17. AtmArpMcMakePacketCopy(
  18. IN PNDIS_PACKET pNdisPacket,
  19. IN PNDIS_BUFFER pNdisBuffer,
  20. IN ULONG TotalLength
  21. )
  22. /*++
  23. Routine Description:
  24. Make a copy of the contents of the given NDIS packet. Allocate
  25. a contiguous piece of memory for this.
  26. Arguments:
  27. pNdisPacket - Pointer to the NDIS packet structure
  28. pNdisBuffer - Pointer to the first NDIS Buffer in the packet
  29. TotalLength - Total Length of the packet
  30. Return Value:
  31. Pointer to the copy, if allocation was successful. Otherwise NULL.
  32. --*/
  33. {
  34. PUCHAR pCopyBuffer;
  35. PUCHAR pCopyDestination;
  36. PUCHAR pNdisData;
  37. ULONG BufferLength;
  38. AA_ALLOC_MEM(pCopyBuffer, UCHAR, TotalLength);
  39. if (pCopyBuffer != (PUCHAR)NULL)
  40. {
  41. pCopyDestination = pCopyBuffer;
  42. while (pNdisBuffer != (PNDIS_BUFFER)NULL)
  43. {
  44. NdisQueryBuffer(
  45. pNdisBuffer,
  46. &pNdisData,
  47. &BufferLength
  48. );
  49. AA_COPY_MEM(pCopyDestination, pNdisData, BufferLength);
  50. pCopyDestination += BufferLength;
  51. pNdisBuffer = NDIS_BUFFER_LINKAGE(pNdisBuffer);
  52. }
  53. }
  54. return (pCopyBuffer);
  55. }
  56. BOOLEAN
  57. AtmArpMcProcessPacket(
  58. IN PATMARP_VC pVc,
  59. IN PNDIS_PACKET pNdisPacket,
  60. IN PNDIS_BUFFER pNdisBuffer,
  61. IN PAA_PKT_LLC_SNAP_HEADER pPktHeader,
  62. IN ULONG TotalLength,
  63. IN ULONG FirstBufferLength
  64. )
  65. /*++
  66. Routine Description:
  67. Process a received packet, which is potentially a MARS control or
  68. multicast data packet. If it is a data packet, pass it up to IP.
  69. Otherwise, process it here.
  70. Arguments:
  71. pVc - Pointer to our VC structure on which the packet
  72. arrived.
  73. pNdisPacket - Pointer to the NDIS packet structure
  74. pNdisBuffer - Pointer to the first NDIS Buffer in the packet
  75. pPktHeader - Pointer to the start of the packet contents
  76. TotalLength - Total packet length
  77. FirstBufferLength - Length of first NDIS buffer in packet.
  78. Return Value:
  79. TRUE if we decide to discard this packet, FALSE if it is a valid packet.
  80. --*/
  81. {
  82. PATMARP_INTERFACE pInterface;
  83. ULONG HeaderLength;
  84. PAA_MC_PKT_TYPE1_SHORT_HEADER pType1Header;
  85. PAA_MC_PKT_TYPE2_SHORT_HEADER pType2Header;
  86. PAA_MARS_PKT_FIXED_HEADER pControlHeader;
  87. BOOLEAN IsIPPacket; // Is this an IP packet?
  88. BOOLEAN DiscardThis; // Should we discard this?
  89. BOOLEAN MadeACopy; // Did we make a copy of this?
  90. AA_MARS_TLV_LIST TlvList;
  91. //
  92. // Initialize
  93. //
  94. IsIPPacket = TRUE;
  95. DiscardThis = FALSE;
  96. MadeACopy = FALSE;
  97. pInterface = pVc->pInterface;
  98. AA_SET_MEM(&TlvList, 0, sizeof(TlvList));
  99. do
  100. {
  101. //
  102. // Check if we have a multicast data packet. Since we only
  103. // support IPv4, we only expect to see short form headers.
  104. //
  105. pType1Header = (PAA_MC_PKT_TYPE1_SHORT_HEADER)pPktHeader;
  106. if (AAMC_PKT_IS_TYPE1_DATA(pType1Header))
  107. {
  108. AAMCDEBUGP(AAD_EXTRA_LOUD,
  109. ("McProcessPacket: pVc 0x%x, Pkt 0x%x, Type 1, %d bytes, CMI %d\n",
  110. pVc, pNdisPacket, TotalLength, pType1Header->cmi));
  111. AAMCDEBUGPDUMP(AAD_EXTRA_LOUD+500, pPktHeader, MIN(FirstBufferLength, 96));
  112. #if DBG
  113. if (AaDataDebugLevel & AAD_DATA_IN)
  114. {
  115. IP_ADDRESS IPAddress;
  116. if ((pVc->pAtmEntry != NULL_PATMARP_ATM_ENTRY) &&
  117. (pVc->pAtmEntry->pIpEntryList != NULL_PATMARP_IP_ENTRY))
  118. {
  119. IPAddress = pVc->pAtmEntry->pIpEntryList->IPAddress;
  120. }
  121. else
  122. {
  123. IPAddress = 0;
  124. }
  125. AADEBUGP(AAD_WARNING,
  126. ("%d <= %d.%d.%d.%d\n",
  127. TotalLength,
  128. ((PUCHAR)&IPAddress)[0],
  129. ((PUCHAR)&IPAddress)[1],
  130. ((PUCHAR)&IPAddress)[2],
  131. ((PUCHAR)&IPAddress)[3]));
  132. }
  133. #endif // DBG
  134. #if 0
  135. //
  136. // Bug #138261: Local clients can never receive multicast packets
  137. // sent out by a local application because of this.
  138. //
  139. if (pType1Header->cmi == pInterface->ClusterMemberId)
  140. {
  141. //
  142. // This is a copy of a packet we sent out.
  143. //
  144. DiscardThis = TRUE;
  145. break;
  146. }
  147. #endif // 0
  148. HeaderLength = sizeof(AA_MC_PKT_TYPE1_SHORT_HEADER);
  149. }
  150. else
  151. {
  152. pType2Header = (PAA_MC_PKT_TYPE2_SHORT_HEADER)pPktHeader;
  153. if (AAMC_PKT_IS_TYPE2_DATA(pType2Header))
  154. {
  155. AAMCDEBUGP(AAD_EXTRA_LOUD,
  156. ("McProcessPacket: pVc 0x%x, pNdisPacket 0x%x, Type 2 data\n",
  157. pVc, pNdisPacket));
  158. HeaderLength = sizeof(AA_MC_PKT_TYPE2_SHORT_HEADER);
  159. }
  160. else
  161. {
  162. IsIPPacket = FALSE;
  163. }
  164. }
  165. if (IsIPPacket)
  166. {
  167. AA_IF_STAT_INCR(pInterface, InNonUnicastPkts);
  168. //
  169. // Send this up to IP. HeaderLength now contains the number
  170. // of header bytes we need to strip off.
  171. //
  172. (pInterface->IPRcvHandler)(
  173. pInterface->IPContext,
  174. (PVOID)((PUCHAR)pPktHeader+HeaderLength),
  175. FirstBufferLength - HeaderLength,
  176. TotalLength - HeaderLength,
  177. (NDIS_HANDLE)pNdisPacket,
  178. HeaderLength,
  179. (UINT)TRUE // Is NON Unicast
  180. #if P2MP
  181. ,NULL
  182. #endif //P2MP
  183. );
  184. break;
  185. }
  186. //
  187. // Check if this is a valid MARS control packet.
  188. //
  189. pControlHeader = (PAA_MARS_PKT_FIXED_HEADER)pPktHeader;
  190. if (AAMC_PKT_IS_CONTROL(pControlHeader))
  191. {
  192. //
  193. // We ignore the checksum (the RFC allows us to do so).
  194. //
  195. AAMCDEBUGP(AAD_EXTRA_LOUD+10,
  196. ("McProcessPacket: pControlHeader 0x%x, Op 0x%x, TotalLen %d\n",
  197. pControlHeader, pControlHeader->op, TotalLength));
  198. //
  199. // If the entire MARS packet isn't in the first NDIS buffer,
  200. // we make a copy into a single contiguous chunk of memory,
  201. // to ease parsing.
  202. //
  203. if (FirstBufferLength == TotalLength)
  204. {
  205. MadeACopy = FALSE;
  206. }
  207. else
  208. {
  209. pControlHeader = (PAA_MARS_PKT_FIXED_HEADER)
  210. AtmArpMcMakePacketCopy(
  211. pNdisPacket,
  212. pNdisBuffer,
  213. TotalLength
  214. );
  215. if (pControlHeader == (PAA_MARS_PKT_FIXED_HEADER)NULL)
  216. {
  217. //
  218. // Allocation failed. Discard this packet.
  219. //
  220. DiscardThis = TRUE;
  221. break;
  222. }
  223. else
  224. {
  225. MadeACopy = TRUE;
  226. }
  227. }
  228. if (!AtmArpMcPreprocess(pControlHeader, TotalLength, &TlvList))
  229. {
  230. AAMCDEBUGP(AAD_INFO,
  231. ("McProcessPacket: PreProcess failed: pHdr 0x%x, TotalLength %d\n",
  232. pControlHeader, TotalLength));
  233. DiscardThis = TRUE;
  234. break;
  235. }
  236. switch (NET_TO_HOST_SHORT(pControlHeader->op))
  237. {
  238. case AA_MARS_OP_TYPE_MULTI:
  239. AtmArpMcHandleMulti(
  240. pVc,
  241. pControlHeader,
  242. TotalLength,
  243. &TlvList
  244. );
  245. break;
  246. case AA_MARS_OP_TYPE_JOIN:
  247. case AA_MARS_OP_TYPE_LEAVE:
  248. AtmArpMcHandleJoinOrLeave(
  249. pVc,
  250. pControlHeader,
  251. TotalLength,
  252. &TlvList
  253. );
  254. break;
  255. case AA_MARS_OP_TYPE_NAK:
  256. AtmArpMcHandleNak(
  257. pVc,
  258. pControlHeader,
  259. TotalLength,
  260. &TlvList
  261. );
  262. break;
  263. case AA_MARS_OP_TYPE_GROUPLIST_REPLY:
  264. AtmArpMcHandleGroupListReply(
  265. pVc,
  266. pControlHeader,
  267. TotalLength,
  268. &TlvList
  269. );
  270. break;
  271. case AA_MARS_OP_TYPE_REDIRECT_MAP:
  272. AtmArpMcHandleRedirectMap(
  273. pVc,
  274. pControlHeader,
  275. TotalLength,
  276. &TlvList
  277. );
  278. break;
  279. case AA_MARS_OP_TYPE_MIGRATE:
  280. AtmArpMcHandleMigrate(
  281. pVc,
  282. pControlHeader,
  283. TotalLength,
  284. &TlvList
  285. );
  286. break;
  287. default:
  288. AAMCDEBUGP(AAD_WARNING,
  289. ("pVc 0x%x, pNdisPacket 0x%x, pHdr 0x%x, bad/unknown op 0x%x\n",
  290. pVc, pNdisPacket, pControlHeader, pControlHeader->op));
  291. AA_ASSERT(FALSE);
  292. break;
  293. } // switch (op)
  294. } // if Control packet
  295. break;
  296. }
  297. while (FALSE);
  298. if (MadeACopy)
  299. {
  300. AA_FREE_MEM(pControlHeader);
  301. }
  302. return (DiscardThis);
  303. }
  304. BOOLEAN
  305. AtmArpMcPreprocess(
  306. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  307. IN ULONG TotalLength,
  308. OUT PAA_MARS_TLV_LIST pTlvList
  309. )
  310. /*++
  311. Routine Description:
  312. Do preliminary checks on a received MARS control packet.
  313. Go through any TLVs, and make sure we can either handle or
  314. safely ignore them. Be prepared to receive complete garbage in this packet.
  315. Update *pTlvList with information about all valid TLVs that we see.
  316. Arguments:
  317. pControlHeader - Pointer to the start of the packet contents
  318. TotalLength - Total length of this packet.
  319. Return Value:
  320. TRUE if the packet passed all checks, FALSE otherwise.
  321. --*/
  322. {
  323. ULONG ExtensionOffset;
  324. PAA_MARS_TLV_HDR pTlv;
  325. ULONG TlvSpaceLeft; // in packet
  326. ULONG TlvLength;
  327. ULONG TlvType;
  328. ULONG TlvAction;
  329. BOOLEAN Passed;
  330. BOOLEAN TlvOk;
  331. Passed = TRUE;
  332. do
  333. {
  334. //
  335. // The USHORT casts below and in obtaining TlvLengths are important
  336. // in order to ensure that these values are less than 2^16.
  337. // Since they are less than 2^16, any sums involving them will not overflow.
  338. //
  339. ExtensionOffset = (USHORT)NET_TO_HOST_SHORT(pControlHeader->extoff);
  340. if (ExtensionOffset != 0)
  341. {
  342. AAMCDEBUGP(AAD_EXTRA_LOUD+20,
  343. ("McPreprocess: pControlHdr 0x%x, ExtOff %d, TotalLength %d\n",
  344. pControlHeader, ExtensionOffset, TotalLength));
  345. //
  346. // Is there space for atleast one TLV?
  347. //
  348. if ((ExtensionOffset
  349. + sizeof(AA_PKT_LLC_SNAP_HEADER) + sizeof(AA_MARS_TLV_HDR))
  350. > TotalLength)
  351. {
  352. Passed = FALSE;
  353. break;
  354. }
  355. pTlv = (PAA_MARS_TLV_HDR)((PUCHAR)pControlHeader +
  356. ExtensionOffset + sizeof(AA_PKT_LLC_SNAP_HEADER));
  357. TlvSpaceLeft = (TotalLength - ExtensionOffset - sizeof(AA_PKT_LLC_SNAP_HEADER));
  358. do
  359. {
  360. TlvType = AAMC_GET_TLV_TYPE(pTlv->Type);
  361. TlvAction = AAMC_GET_TLV_ACTION(pTlv->Type);
  362. //
  363. // Get the rounded-off TLV length
  364. //
  365. TlvLength = (USHORT) NET_TO_HOST_SHORT(pTlv->Length);
  366. TlvLength = AAMC_GET_TLV_TOTAL_LENGTH(TlvLength);
  367. if (TlvLength > TlvSpaceLeft)
  368. {
  369. AAMCDEBUGP(AAD_WARNING,
  370. ("McPreprocess: Hdr 0x%x, pTlv 0x%x: TlvLength %d > TlvSpaceLeft %d\n",
  371. pControlHeader, pTlv, TlvLength, TlvSpaceLeft));
  372. Passed = FALSE;
  373. break;
  374. }
  375. TlvOk = FALSE;
  376. switch (TlvType)
  377. {
  378. case AAMC_TLVT_MULTI_IS_MCS:
  379. if (TlvLength == sizeof(AA_MARS_TLV_MULTI_IS_MCS))
  380. {
  381. TlvOk = TRUE;
  382. pTlvList->MultiIsMCSPresent =
  383. pTlvList->MultiIsMCSValue = TRUE;
  384. }
  385. break;
  386. case AAMC_TLVT_NULL:
  387. if (TlvLength == 0)
  388. {
  389. TlvOk = TRUE;
  390. }
  391. break;
  392. default:
  393. break;
  394. }
  395. if (!TlvOk)
  396. {
  397. if (TlvAction == AA_MARS_TLV_TA_STOP_SILENT)
  398. {
  399. Passed = FALSE;
  400. break;
  401. }
  402. if (TlvAction == AA_MARS_TLV_TA_STOP_LOG)
  403. {
  404. AA_LOG_ERROR();
  405. Passed = FALSE;
  406. break;
  407. }
  408. }
  409. pTlv = (PAA_MARS_TLV_HDR)((PUCHAR)pTlv + TlvLength);
  410. TlvSpaceLeft -= TlvLength;
  411. }
  412. while (TlvSpaceLeft >= sizeof(AA_MARS_TLV_HDR));
  413. if (TlvSpaceLeft != 0)
  414. {
  415. //
  416. // Improperly formed TLV at the end of the packet.
  417. //
  418. AAMCDEBUGP(AAD_LOUD,
  419. ("McPreprocess: residual space left at end of Pkt 0x%x: %d bytes\n",
  420. pControlHeader, TlvSpaceLeft));
  421. Passed = FALSE;
  422. }
  423. }
  424. break;
  425. }
  426. while (FALSE);
  427. return (Passed);
  428. }
  429. VOID
  430. AtmArpMcHandleMulti(
  431. IN PATMARP_VC pVc,
  432. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  433. IN ULONG TotalLength,
  434. IN PAA_MARS_TLV_LIST pTlvList
  435. )
  436. /*++
  437. Routine Description:
  438. Process a received MARS_MULTI message. We first look up the IP Entry
  439. for the group address being resolved/revalidated. If we aren't
  440. in "Discard mode" on this entry and the MULTI sequence number is ok,
  441. then we add all ATM endstations returned in this MULTI (that aren't
  442. present already) to the ATM Entry for this multicast group.
  443. If this is the last MULTI for the multicast group, we initiate/update
  444. our point-to-multipoint connection for sending data to the group.
  445. Arguments:
  446. pVc - Pointer to our VC structure on which the packet
  447. arrived.
  448. pControlHeader - Pointer to the start of the packet contents
  449. TotalLength - Total length of this packet.
  450. pTlvList - All TLVs seen in this packet
  451. Return Value:
  452. None
  453. --*/
  454. {
  455. PATMARP_INTERFACE pInterface;
  456. PAA_MARS_MULTI_HEADER pMultiHeader;
  457. PATMARP_IP_ENTRY pIpEntry; // Entry for IP address being resolved
  458. PATMARP_IPMC_ATM_ENTRY pMcAtmEntry;
  459. ULONG MarsSeqNumber; // MSN received in this packet
  460. ULONG HostSeqNumber; // Our MSN
  461. ULONG SeqDiff; // Difference between MSN and the HSN
  462. USHORT SequenceNoY; // MULTI sequence number
  463. BOOLEAN IsLastMulti; // Is this the final MULTI response?
  464. BOOLEAN bWasRunning; // Was a timer running?
  465. IP_ADDRESS IPAddress; // the address being queried
  466. PNDIS_PACKET pPacketList;
  467. BOOLEAN IsUnicastResolution; // Did we resolve to a single MCS?
  468. //
  469. // Initialize
  470. //
  471. pInterface = pVc->pInterface;
  472. SeqDiff = 0;
  473. pMultiHeader = (PAA_MARS_MULTI_HEADER)pControlHeader;
  474. do
  475. {
  476. ULONG rc;
  477. //
  478. // Get the sequence number of this MARS MULTI.
  479. //
  480. SequenceNoY = NET_TO_HOST_SHORT(pMultiHeader->seqxy);
  481. IsLastMulti = ((SequenceNoY & AA_MARS_X_MASK) != 0);
  482. SequenceNoY = (SequenceNoY & AA_MARS_Y_MASK);
  483. //
  484. // Get the MARS Sequence Number in this message.
  485. //
  486. MarsSeqNumber = NET_TO_HOST_LONG(pMultiHeader->msn);
  487. //
  488. // If this is the last MULTI in reply to our REQUEST,
  489. // calculate the Seq # difference.
  490. //
  491. if (IsLastMulti)
  492. {
  493. AA_ACQUIRE_IF_LOCK(pInterface);
  494. HostSeqNumber = pInterface->HostSeqNumber; // save the old value
  495. pInterface->HostSeqNumber = MarsSeqNumber; // and update
  496. AA_RELEASE_IF_LOCK(pInterface);
  497. SeqDiff = MarsSeqNumber - HostSeqNumber;
  498. }
  499. //
  500. // Get the group address being responded to.
  501. //
  502. IPAddress = *(IP_ADDRESS UNALIGNED *)(
  503. (PUCHAR)pMultiHeader +
  504. sizeof(AA_MARS_MULTI_HEADER) +
  505. (pMultiHeader->shtl & ~AA_PKT_ATM_ADDRESS_BIT) +
  506. (pMultiHeader->sstl & ~AA_PKT_ATM_ADDRESS_BIT) +
  507. (pMultiHeader->spln)
  508. );
  509. AAMCDEBUGP(AAD_LOUD,
  510. ("McHandleMulti: 0x%x, IP %d.%d.%d.%d, MSN %d, HSN %d, Last %d, Y %d, tnum %d\n",
  511. pMultiHeader,
  512. ((PUCHAR)&IPAddress)[0],
  513. ((PUCHAR)&IPAddress)[1],
  514. ((PUCHAR)&IPAddress)[2],
  515. ((PUCHAR)&IPAddress)[3],
  516. MarsSeqNumber,
  517. HostSeqNumber,
  518. (ULONG)IsLastMulti,
  519. (ULONG)SequenceNoY,
  520. NET_TO_HOST_SHORT(pMultiHeader->tnum)
  521. ));
  522. //
  523. // Get the IP Entry for this address.
  524. //
  525. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  526. pIpEntry = AtmArpSearchForIPAddress(
  527. pInterface,
  528. &IPAddress,
  529. IE_REFTYPE_AE,
  530. TRUE, // this is a multicast/broadcast address
  531. FALSE // don't create a new entry if the address isn't found
  532. );
  533. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  534. //
  535. // AtmArpSearchForIPAddress addreffs pIpEntry for us ...
  536. //
  537. if (pIpEntry == NULL_PATMARP_IP_ENTRY)
  538. {
  539. AAMCDEBUGP(AAD_INFO, ("McHandleMulti: No IP Entry for %d.%d.%d.%d\n",
  540. ((PUCHAR)&IPAddress)[0],
  541. ((PUCHAR)&IPAddress)[1],
  542. ((PUCHAR)&IPAddress)[2],
  543. ((PUCHAR)&IPAddress)[3]));
  544. break;
  545. }
  546. AA_ACQUIRE_IE_LOCK(pIpEntry);
  547. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  548. //
  549. // A resolution timer may be running here - stop it.
  550. //
  551. bWasRunning = AtmArpStopTimer(&(pIpEntry->Timer), pInterface);
  552. if (bWasRunning)
  553. {
  554. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  555. AA_ASSERT(rc != 0);
  556. }
  557. IsUnicastResolution = (IsLastMulti &&
  558. (NET_TO_HOST_SHORT(pMultiHeader->tnum) == 1) &&
  559. (pTlvList->MultiIsMCSValue == TRUE));
  560. //
  561. // Check if the multi request is compatible with the existing atm
  562. // entry (if any) associated with the ip entry. If they are not,
  563. // then we must abort the IP entry and get out of here, because
  564. // there was possibly a switch in status of this IP group address from
  565. // being vc-mesh served to mcs served, or vice versa.
  566. //
  567. if (pIpEntry->pAtmEntry)
  568. {
  569. if ( (IsUnicastResolution && pIpEntry->pAtmEntry->pMcAtmInfo != NULL)
  570. || (!IsUnicastResolution && pIpEntry->pAtmEntry->pMcAtmInfo ==NULL))
  571. {
  572. AAMCDEBUGP(AAD_WARNING,
  573. ("HandleMulti: Type Mismatch! %s pIpEntry 0x%x/%x (%d.%d.%d.%d) linked to ATMEntry 0x%x\n",
  574. ((IsUnicastResolution) ? "MCS" : "VC-Mesh"),
  575. pIpEntry, pIpEntry->Flags,
  576. ((PUCHAR)&(pIpEntry->IPAddress))[0],
  577. ((PUCHAR)&(pIpEntry->IPAddress))[1],
  578. ((PUCHAR)&(pIpEntry->IPAddress))[2],
  579. ((PUCHAR)&(pIpEntry->IPAddress))[3],
  580. pIpEntry->pAtmEntry));
  581. //
  582. // Remove the AE_REF implicitly added by AtmArpMcLookupAtmMember
  583. // above...
  584. //
  585. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_AE); // Tmp ref
  586. if (rc!=0)
  587. {
  588. AtmArpAbortIPEntry(pIpEntry);
  589. //
  590. // IE lock is released within the above.
  591. //
  592. }
  593. break;
  594. }
  595. }
  596. //
  597. // Check if we are in discard mode, or this MULTI has a bad
  598. // sequence number. In either case, discard this MULTI, otherwise
  599. // process it.
  600. //
  601. if (!AA_IS_FLAG_SET(
  602. pIpEntry->Flags,
  603. AA_IP_ENTRY_MC_RESOLVE_MASK,
  604. AA_IP_ENTRY_MC_DISCARDING_MULTI
  605. ) &&
  606. (SequenceNoY == pIpEntry->NextMultiSeq))
  607. {
  608. PATMARP_ATM_ENTRY pAtmEntry;
  609. //
  610. // Total entries in this MULTI
  611. //
  612. ULONG NumberOfEntries;
  613. //
  614. // All info about one ATM (leaf) entry:
  615. //
  616. PUCHAR pAtmNumber;
  617. ULONG AtmNumberLength;
  618. ATM_ADDRESSTYPE AtmNumberType;
  619. PUCHAR pAtmSubaddress;
  620. ULONG AtmSubaddressLength;
  621. ATM_ADDRESSTYPE AtmSubaddressType;
  622. //
  623. // Process this MARS MULTI.
  624. //
  625. pIpEntry->NextMultiSeq++;
  626. AA_PKT_TYPE_LEN_TO_ATM_ADDRESS(
  627. pMultiHeader->thtl,
  628. &AtmNumberType,
  629. &AtmNumberLength);
  630. AA_PKT_TYPE_LEN_TO_ATM_ADDRESS(
  631. pMultiHeader->tstl,
  632. &AtmSubaddressType,
  633. &AtmSubaddressLength);
  634. pAtmNumber = ((PUCHAR)pMultiHeader +
  635. sizeof(AA_MARS_MULTI_HEADER) +
  636. (pMultiHeader->shtl & ~AA_PKT_ATM_ADDRESS_BIT) +
  637. (pMultiHeader->sstl & ~AA_PKT_ATM_ADDRESS_BIT) +
  638. (pMultiHeader->spln) +
  639. (pMultiHeader->tpln));
  640. if (IsUnicastResolution)
  641. {
  642. //
  643. // This IP address has resolved to a single ATM address. Search
  644. // for (or allocate a new) ATM Entry for this address.
  645. //
  646. AAMCDEBUGP(AAD_LOUD, ("McHandleMulti: Unicast res for %d.%d.%d.%d\n",
  647. ((PUCHAR)&IPAddress)[0],
  648. ((PUCHAR)&IPAddress)[1],
  649. ((PUCHAR)&IPAddress)[2],
  650. ((PUCHAR)&IPAddress)[3]));
  651. AA_RELEASE_IE_LOCK(pIpEntry);
  652. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  653. pAtmEntry = AtmArpSearchForAtmAddress(
  654. pInterface,
  655. pMultiHeader->thtl,
  656. pAtmNumber,
  657. pMultiHeader->tstl,
  658. (PUCHAR)pAtmNumber + AtmNumberLength,
  659. AE_REFTYPE_IE,
  660. TRUE
  661. );
  662. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  663. AA_ACQUIRE_IE_LOCK(pIpEntry);
  664. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  665. if ( pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  666. {
  667. AAMCDEBUGP(AAD_INFO,
  668. ("McHandleMulti: pIpEntry 0x%x, failed to alloc AtmEntry\n",
  669. pIpEntry));
  670. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_AE); // Tmp ref
  671. if (rc!=0)
  672. {
  673. AtmArpAbortIPEntry(pIpEntry);
  674. //
  675. // IE lock is released within the above.
  676. //
  677. }
  678. break; // go to end of processing
  679. }
  680. AA_ACQUIRE_AE_LOCK_DPC(pAtmEntry);
  681. //
  682. // AtmArpSearchForAtmAddress addrefs pAtmEntry for us..
  683. //
  684. if (pIpEntry->pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  685. {
  686. //
  687. // Link the ATM Entry to this IP Entry.
  688. //
  689. pIpEntry->pAtmEntry = pAtmEntry;
  690. AA_SET_FLAG(pAtmEntry->Flags,
  691. AA_ATM_ENTRY_STATE_MASK,
  692. AA_ATM_ENTRY_ACTIVE);
  693. //
  694. // Add the IP Entry to the ATM Entry's list of IP Entries
  695. // (multiple IP entries could point to the same ATM Entry).
  696. //
  697. pIpEntry->pNextToAtm = pAtmEntry->pIpEntryList;
  698. pAtmEntry->pIpEntryList = pIpEntry;
  699. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  700. }
  701. else
  702. {
  703. //
  704. // There is already a linkage -- deref the
  705. // references implicitly added for us in the
  706. // SearchForXXX calls above...
  707. //
  708. rc = AA_DEREF_AE(pAtmEntry, AE_REFTYPE_IE); // IP
  709. {
  710. if (rc != 0)
  711. {
  712. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  713. }
  714. }
  715. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_AE); // AE
  716. if (rc==0)
  717. {
  718. //
  719. // IpEntry gone away...
  720. //
  721. break;
  722. }
  723. }
  724. //
  725. // At this point we have a lock on pIpEntry, but none
  726. // on pAtmEntry, and we don't have any "extra" refs on
  727. // either.
  728. //
  729. if (pIpEntry->pAtmEntry == pAtmEntry)
  730. {
  731. //
  732. // Either a fresh IP->ATM resolution, or
  733. // reconfirmation of an existing resolution.
  734. //
  735. AAMCDEBUGPATMADDR(AAD_EXTRA_LOUD, "MULTI: Unicast Addr: ", &pAtmEntry->ATMAddress);
  736. //
  737. // Update IP Entry state.
  738. //
  739. AA_SET_FLAG(pIpEntry->Flags,
  740. AA_IP_ENTRY_MC_RESOLVE_MASK,
  741. AA_IP_ENTRY_MC_RESOLVED);
  742. AA_SET_FLAG(pIpEntry->Flags,
  743. AA_IP_ENTRY_MC_VALIDATE_MASK,
  744. AA_IP_ENTRY_MC_NO_REVALIDATION);
  745. AA_SET_FLAG(pIpEntry->Flags,
  746. AA_IP_ENTRY_STATE_MASK,
  747. AA_IP_ENTRY_RESOLVED);
  748. pIpEntry->NextMultiSeq = AA_MARS_INITIAL_Y;
  749. #ifdef AGE_MCAST_IP_ENTRIES
  750. //
  751. // Feb 26, 97: we don't need to age out IP multicast entries:
  752. // VC aging timer is sufficient.
  753. //
  754. //
  755. // Start off IP Aging timeout
  756. //
  757. AtmArpStartTimer(
  758. pInterface,
  759. &(pIpEntry->Timer),
  760. AtmArpIPEntryAgingTimeout,
  761. pInterface->MulticastEntryAgingTimeout,
  762. (PVOID)pIpEntry
  763. );
  764. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // timer ref
  765. #endif // AGE_MCAST_IP_ENTRIES
  766. //
  767. // Remove the packet list queued on this IP Entry,
  768. // if any.
  769. //
  770. pPacketList = pIpEntry->PacketList;
  771. pIpEntry->PacketList = (PNDIS_PACKET)NULL;
  772. AA_RELEASE_IE_LOCK(pIpEntry);
  773. if (pPacketList != (PNDIS_PACKET)NULL)
  774. {
  775. //
  776. // The following will trigger off MakeCall.
  777. //
  778. AtmArpSendPacketListOnAtmEntry(
  779. pInterface,
  780. pAtmEntry,
  781. pPacketList,
  782. TRUE
  783. );
  784. }
  785. }
  786. else
  787. {
  788. AAMCDEBUGP(AAD_WARNING,
  789. ("HandleMulti: pIpEntry 0x%x/%x (%d.%d.%d.%d) linked to ATMEntry 0x%x, resolves to 0x%x\n",
  790. pIpEntry, pIpEntry->Flags,
  791. ((PUCHAR)&(pIpEntry->IPAddress))[0],
  792. ((PUCHAR)&(pIpEntry->IPAddress))[1],
  793. ((PUCHAR)&(pIpEntry->IPAddress))[2],
  794. ((PUCHAR)&(pIpEntry->IPAddress))[3],
  795. pIpEntry->pAtmEntry,
  796. pAtmEntry));
  797. AA_STRUCT_ASSERT(pIpEntry->pAtmEntry, aae);
  798. AtmArpAbortIPEntry(pIpEntry);
  799. //
  800. // IE lock is released within the above.
  801. //
  802. }
  803. break; // go to end of processing
  804. } // Unicast resolution
  805. //
  806. // IP Address resolved to multiple ATM addresses.
  807. //
  808. pAtmEntry = pIpEntry->pAtmEntry;
  809. if (pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  810. {
  811. //
  812. // Allocate an ATM Entry and link to this IP Entry.
  813. //
  814. pAtmEntry = AtmArpAllocateAtmEntry(pInterface, TRUE);
  815. if (pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  816. {
  817. // Let's deref the implicit addref for pIpEntry...
  818. // Warning -- we should now not release our lock on
  819. // pIpEntry until we're completely done with it
  820. // (unless we first addref it).
  821. //
  822. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_AE); // Tmp ref
  823. if (rc!=0)
  824. {
  825. AtmArpAbortIPEntry(pIpEntry);
  826. //
  827. // IE lock is released within the above.
  828. //
  829. }
  830. break; // go to end of processing
  831. }
  832. //
  833. // Link them together.
  834. //
  835. pIpEntry->pAtmEntry = pAtmEntry;
  836. pAtmEntry->pIpEntryList = pIpEntry;
  837. AAMCDEBUGP(AAD_EXTRA_LOUD,
  838. ("McHandleMulti: Multicast: linked pIpEntry 0x%x, pAtmEntry 0x%x\n",
  839. pIpEntry, pAtmEntry));
  840. AA_REF_AE(pAtmEntry, AE_REFTYPE_IE); // IP Entry linkage
  841. //
  842. // Link the ATM entry to this Interface
  843. //
  844. AA_RELEASE_IE_LOCK(pIpEntry);
  845. AA_ACQUIRE_IF_ATM_LIST_LOCK(pInterface);
  846. if (pInterface->AtmEntryListUp)
  847. {
  848. pAtmEntry->pNext = pInterface->pAtmEntryList;
  849. pInterface->pAtmEntryList = pAtmEntry;
  850. }
  851. AA_RELEASE_IF_ATM_LIST_LOCK(pInterface);
  852. AA_ACQUIRE_IE_LOCK(pIpEntry);
  853. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  854. }
  855. else
  856. {
  857. //
  858. // IP already has an atm entry...
  859. //
  860. // Let's deref the implicit addref for pIpEntry...
  861. // Warning -- we should now not release our lock on
  862. // pIpEntry until we're completely done with it
  863. // (unless we first addref it).
  864. //
  865. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_AE); // Tmp ref
  866. if (rc==0)
  867. {
  868. //
  869. // IpEntry gone away...
  870. //
  871. break;
  872. }
  873. }
  874. AA_ACQUIRE_AE_LOCK_DPC(pAtmEntry);
  875. for (NumberOfEntries = NET_TO_HOST_SHORT(pMultiHeader->tnum);
  876. NumberOfEntries != 0;
  877. NumberOfEntries--)
  878. {
  879. pAtmSubaddress = ((PUCHAR)pAtmNumber + AtmNumberLength);
  880. pMcAtmEntry = AtmArpMcLookupAtmMember(
  881. pAtmEntry,
  882. &(pAtmEntry->pMcAtmInfo->pMcAtmEntryList),
  883. pAtmNumber,
  884. AtmNumberLength,
  885. AtmNumberType,
  886. pAtmSubaddress,
  887. AtmSubaddressLength,
  888. TRUE // Create new entry if not found
  889. );
  890. if (pMcAtmEntry != NULL_PATMARP_IPMC_ATM_ENTRY)
  891. {
  892. //
  893. // Mark this member "valid".
  894. //
  895. AA_SET_FLAG(
  896. pMcAtmEntry->Flags,
  897. AA_IPMC_AE_GEN_STATE_MASK,
  898. AA_IPMC_AE_VALID);
  899. AAMCDEBUGPATMADDR(AAD_EXTRA_LOUD, "MULTI Addr: ", &pMcAtmEntry->ATMAddress);
  900. }
  901. else
  902. {
  903. //
  904. // Resource problems! No point in continuing.
  905. //
  906. break;
  907. }
  908. pAtmNumber = (PUCHAR)pAtmNumber + AtmNumberLength;
  909. } // for
  910. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  911. if (IsLastMulti)
  912. {
  913. //
  914. // We have successfully resolved this Multicast IP Address.
  915. //
  916. AAMCDEBUGP(AAD_INFO,
  917. ("### HandleMulti: pIpEntry 0x%x, resolved %d.%d.%d.%d\n",
  918. pIpEntry,
  919. ((PUCHAR)(&IPAddress))[0],
  920. ((PUCHAR)(&IPAddress))[1],
  921. ((PUCHAR)(&IPAddress))[2],
  922. ((PUCHAR)(&IPAddress))[3]));
  923. AA_SET_FLAG(pIpEntry->Flags,
  924. AA_IP_ENTRY_MC_RESOLVE_MASK,
  925. AA_IP_ENTRY_MC_RESOLVED);
  926. AA_SET_FLAG(pIpEntry->Flags,
  927. AA_IP_ENTRY_MC_VALIDATE_MASK,
  928. AA_IP_ENTRY_MC_NO_REVALIDATION);
  929. AA_SET_FLAG(pIpEntry->Flags,
  930. AA_IP_ENTRY_STATE_MASK,
  931. AA_IP_ENTRY_RESOLVED);
  932. pIpEntry->NextMultiSeq = AA_MARS_INITIAL_Y;
  933. //
  934. // Remove the packet list queued on this IP Entry,
  935. // if any.
  936. //
  937. pPacketList = pIpEntry->PacketList;
  938. pIpEntry->PacketList = (PNDIS_PACKET)NULL;
  939. #ifdef AGE_MCAST_IP_ENTRIES
  940. //
  941. // Start off IP Aging timeout
  942. //
  943. AtmArpStartTimer(
  944. pInterface,
  945. &(pIpEntry->Timer),
  946. AtmArpIPEntryAgingTimeout,
  947. pInterface->MulticastEntryAgingTimeout,
  948. (PVOID)pIpEntry
  949. );
  950. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // timer ref
  951. #endif // AGE_MCAST_IP_ENTRIES
  952. AA_RELEASE_IE_LOCK(pIpEntry);
  953. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  954. AA_REF_AE(pAtmEntry, AE_REFTYPE_TMP);
  955. AtmArpMcUpdateConnection(pAtmEntry);
  956. //
  957. // AE Lock is released within the above.
  958. //
  959. if (pPacketList != (PNDIS_PACKET)NULL)
  960. {
  961. AtmArpSendPacketListOnAtmEntry(
  962. pInterface,
  963. pAtmEntry,
  964. pPacketList,
  965. TRUE
  966. );
  967. }
  968. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  969. rc = AA_DEREF_AE(pAtmEntry, AE_REFTYPE_TMP);
  970. if (rc != 0)
  971. {
  972. AA_RELEASE_AE_LOCK(pAtmEntry);
  973. }
  974. }
  975. else
  976. {
  977. //
  978. // Restart the address resolution timer on this entry,
  979. // but for a duration equal to the max delay between
  980. // MULTI messages.
  981. //
  982. AtmArpStartTimer(
  983. pInterface,
  984. &(pIpEntry->Timer),
  985. AtmArpAddressResolutionTimeout,
  986. pInterface->MaxDelayBetweenMULTIs,
  987. (PVOID)pIpEntry
  988. );
  989. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Delay b/w MULTI timer ref
  990. AA_RELEASE_IE_LOCK(pIpEntry);
  991. }
  992. }
  993. else
  994. {
  995. AAMCDEBUGP(AAD_WARNING,
  996. ("HandleMULTI: fail condition: pIpEntry 0x%x/0x%x, Addr %d.%d.%d.%d, SeqY %d, NextMultiSeq %d, IsLastMulti %d\n",
  997. pIpEntry,
  998. pIpEntry->Flags,
  999. ((PUCHAR)&(pIpEntry->IPAddress))[0],
  1000. ((PUCHAR)&(pIpEntry->IPAddress))[1],
  1001. ((PUCHAR)&(pIpEntry->IPAddress))[2],
  1002. ((PUCHAR)&(pIpEntry->IPAddress))[3],
  1003. SequenceNoY,
  1004. pIpEntry->NextMultiSeq,
  1005. IsLastMulti
  1006. ));
  1007. //
  1008. // A "failure condition" with this MULTI.
  1009. //
  1010. if (IsLastMulti)
  1011. {
  1012. //
  1013. // This is the last MULTI of a failed address resolution
  1014. // sequence. Start off address resolution afresh.
  1015. //
  1016. AA_SET_FLAG(pIpEntry->Flags,
  1017. AA_IP_ENTRY_STATE_MASK,
  1018. AA_IP_ENTRY_IDLE2);
  1019. AtmArpResolveIpEntry(pIpEntry);
  1020. //
  1021. // IE Lock is released within the above.
  1022. //
  1023. }
  1024. else
  1025. {
  1026. //
  1027. // Discard all future MULTIs
  1028. //
  1029. AA_SET_FLAG(pIpEntry->Flags,
  1030. AA_IP_ENTRY_MC_RESOLVE_MASK,
  1031. AA_IP_ENTRY_MC_DISCARDING_MULTI);
  1032. AA_RELEASE_IE_LOCK(pIpEntry);
  1033. }
  1034. }
  1035. break;
  1036. }
  1037. while (FALSE);
  1038. //
  1039. // Finally (according to Section 5.1.4.2 of RFC 2022), check
  1040. // if we just had a jump in the MSN.
  1041. //
  1042. if ((SeqDiff != 1) && (SeqDiff != 0))
  1043. {
  1044. AAMCDEBUGP(AAD_INFO,
  1045. ("HandleMulti: IF 0x%x: Bad seq diff %d, MSN 0x%x, HSN 0x%x\n",
  1046. pInterface, SeqDiff, MarsSeqNumber, HostSeqNumber));
  1047. AtmArpMcRevalidateAll(pInterface);
  1048. }
  1049. }
  1050. VOID
  1051. AtmArpMcHandleMigrate(
  1052. IN PATMARP_VC pVc,
  1053. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  1054. IN ULONG TotalLength,
  1055. IN PAA_MARS_TLV_LIST pTlvList
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. Arguments:
  1060. Return Value:
  1061. None
  1062. --*/
  1063. {
  1064. PATMARP_INTERFACE pInterface;
  1065. PAA_MARS_MIGRATE_HEADER pMigrateHeader;
  1066. PATMARP_IP_ENTRY pIpEntry; // Entry for IP address being resolved
  1067. PATMARP_IPMC_ATM_ENTRY pMcAtmEntry;
  1068. PATMARP_ATM_ENTRY pAtmEntry;
  1069. ULONG MarsSeqNumber; // MSN received in this packet
  1070. ULONG HostSeqNumber; // Our MSN
  1071. ULONG SeqDiff; // Difference between MSN and the HSN
  1072. BOOLEAN bWasRunning; // Was a timer running?
  1073. IP_ADDRESS IPAddress; // the address being queried
  1074. //
  1075. // Initialize
  1076. //
  1077. pInterface = pVc->pInterface;
  1078. SeqDiff = 0;
  1079. pMigrateHeader = (PAA_MARS_MIGRATE_HEADER)pControlHeader;
  1080. do
  1081. {
  1082. //
  1083. // Get the MARS Sequence Number in this message.
  1084. //
  1085. MarsSeqNumber = NET_TO_HOST_LONG(pMigrateHeader->msn);
  1086. //
  1087. // Calculate the Seq # difference.
  1088. //
  1089. AA_ACQUIRE_IF_LOCK(pInterface);
  1090. HostSeqNumber = pInterface->HostSeqNumber; // save the old value
  1091. pInterface->HostSeqNumber = MarsSeqNumber; // and update
  1092. AA_RELEASE_IF_LOCK(pInterface);
  1093. SeqDiff = MarsSeqNumber - HostSeqNumber;
  1094. //
  1095. // Get the group address being migrated.
  1096. //
  1097. IPAddress = *(IP_ADDRESS UNALIGNED *)(
  1098. (PUCHAR)pMigrateHeader +
  1099. sizeof(AA_MARS_MIGRATE_HEADER) +
  1100. (pMigrateHeader->shtl & ~AA_PKT_ATM_ADDRESS_BIT) +
  1101. (pMigrateHeader->sstl & ~AA_PKT_ATM_ADDRESS_BIT) +
  1102. (pMigrateHeader->spln)
  1103. );
  1104. AAMCDEBUGP(AAD_LOUD,
  1105. ("McHandleMigrate: 0x%x, IP %d.%d.%d.%d, MSN %d, HSN %d\n",
  1106. pMigrateHeader,
  1107. ((PUCHAR)&IPAddress)[0],
  1108. ((PUCHAR)&IPAddress)[1],
  1109. ((PUCHAR)&IPAddress)[2],
  1110. ((PUCHAR)&IPAddress)[3],
  1111. MarsSeqNumber,
  1112. HostSeqNumber));
  1113. //
  1114. // Get the IP Entry for this address.
  1115. //
  1116. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1117. pIpEntry = AtmArpSearchForIPAddress(
  1118. pInterface,
  1119. &IPAddress,
  1120. IE_REFTYPE_TMP,
  1121. TRUE, // this is a multicast/broadcast address
  1122. FALSE // don't create a new entry if the address isn't found
  1123. );
  1124. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1125. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1126. {
  1127. //
  1128. // AtmArpSearchForIPAddress addrefs pIpEntry for us ...
  1129. //
  1130. ULONG rc;
  1131. AA_ACQUIRE_IE_LOCK(pIpEntry);
  1132. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  1133. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TMP);
  1134. if (rc == 0)
  1135. {
  1136. // Oops, IP address has gone away...
  1137. pIpEntry = NULL_PATMARP_IP_ENTRY;
  1138. }
  1139. }
  1140. if (pIpEntry == NULL_PATMARP_IP_ENTRY)
  1141. {
  1142. AAMCDEBUGP(AAD_INFO, ("McHandleMigrate: No IP Entry for %d.%d.%d.%d\n",
  1143. ((PUCHAR)&IPAddress)[0],
  1144. ((PUCHAR)&IPAddress)[1],
  1145. ((PUCHAR)&IPAddress)[2],
  1146. ((PUCHAR)&IPAddress)[3]));
  1147. break;
  1148. }
  1149. if (pIpEntry->pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  1150. {
  1151. //
  1152. // This IP address is being resolved.
  1153. //
  1154. AA_RELEASE_IE_LOCK(pIpEntry);
  1155. break;
  1156. }
  1157. pAtmEntry = pIpEntry->pAtmEntry;
  1158. if (AA_IS_FLAG_SET(
  1159. pAtmEntry->Flags,
  1160. AA_ATM_ENTRY_TYPE_MASK,
  1161. AA_ATM_ENTRY_TYPE_UCAST))
  1162. {
  1163. AAMCDEBUGP(AAD_INFO,
  1164. ("McHandleMigrate: IP Addr %d.%d.%d.%d was unicast, aborting pIpEntry 0x%x\n",
  1165. ((PUCHAR)&IPAddress)[0],
  1166. ((PUCHAR)&IPAddress)[1],
  1167. ((PUCHAR)&IPAddress)[2],
  1168. ((PUCHAR)&IPAddress)[3],
  1169. pIpEntry));
  1170. AtmArpAbortIPEntry(pIpEntry);
  1171. //
  1172. // IE Lock is released within the above.
  1173. //
  1174. break;
  1175. }
  1176. //
  1177. // Check if we are in discard mode.
  1178. //
  1179. if (!AA_IS_FLAG_SET(
  1180. pIpEntry->Flags,
  1181. AA_IP_ENTRY_MC_RESOLVE_MASK,
  1182. AA_IP_ENTRY_MC_DISCARDING_MULTI))
  1183. {
  1184. //
  1185. // Total entries in this MULTI
  1186. //
  1187. ULONG NumberOfEntries;
  1188. //
  1189. // All info about one ATM (leaf) entry:
  1190. //
  1191. PUCHAR pAtmNumber;
  1192. ULONG AtmNumberLength;
  1193. ATM_ADDRESSTYPE AtmNumberType;
  1194. PUCHAR pAtmSubaddress;
  1195. ULONG AtmSubaddressLength;
  1196. ATM_ADDRESSTYPE AtmSubaddressType;
  1197. //
  1198. // Process this MARS MIGRATE fully.
  1199. //
  1200. AA_PKT_TYPE_LEN_TO_ATM_ADDRESS(
  1201. pMigrateHeader->thtl,
  1202. &AtmNumberType,
  1203. &AtmNumberLength);
  1204. AA_PKT_TYPE_LEN_TO_ATM_ADDRESS(
  1205. pMigrateHeader->tstl,
  1206. &AtmSubaddressType,
  1207. &AtmSubaddressLength);
  1208. pAtmNumber = ((PUCHAR)pMigrateHeader +
  1209. sizeof(AA_MARS_MIGRATE_HEADER) +
  1210. (pMigrateHeader->shtl & ~AA_PKT_ATM_ADDRESS_BIT) +
  1211. (pMigrateHeader->sstl & ~AA_PKT_ATM_ADDRESS_BIT) +
  1212. (pMigrateHeader->spln) +
  1213. (pMigrateHeader->tpln));
  1214. AA_ACQUIRE_AE_LOCK_DPC(pAtmEntry);
  1215. for (NumberOfEntries = pMigrateHeader->tnum;
  1216. NumberOfEntries != 0;
  1217. NumberOfEntries--)
  1218. {
  1219. pAtmSubaddress = ((PUCHAR)pAtmNumber + AtmNumberLength);
  1220. pMcAtmEntry = AtmArpMcLookupAtmMember(
  1221. pAtmEntry,
  1222. &(pAtmEntry->pMcAtmInfo->pMcAtmMigrateList),
  1223. pAtmNumber,
  1224. AtmNumberLength,
  1225. AtmNumberType,
  1226. pAtmSubaddress,
  1227. AtmSubaddressLength,
  1228. TRUE // Create new entry if not found
  1229. );
  1230. if (pMcAtmEntry != NULL_PATMARP_IPMC_ATM_ENTRY)
  1231. {
  1232. //
  1233. // Mark this member "valid".
  1234. //
  1235. AA_SET_FLAG(
  1236. pMcAtmEntry->Flags,
  1237. AA_IPMC_AE_GEN_STATE_MASK,
  1238. AA_IPMC_AE_VALID);
  1239. }
  1240. else
  1241. {
  1242. //
  1243. // Resource problems! No point in continuing.
  1244. //
  1245. break;
  1246. }
  1247. pAtmNumber = (PUCHAR)pAtmNumber + AtmNumberLength;
  1248. } // for
  1249. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  1250. AA_SET_FLAG(pIpEntry->Flags,
  1251. AA_IP_ENTRY_MC_RESOLVE_MASK,
  1252. AA_IP_ENTRY_MC_RESOLVED);
  1253. AA_SET_FLAG(pIpEntry->Flags,
  1254. AA_IP_ENTRY_MC_VALIDATE_MASK,
  1255. AA_IP_ENTRY_MC_NO_REVALIDATION);
  1256. AA_SET_FLAG(pIpEntry->Flags,
  1257. AA_IP_ENTRY_STATE_MASK,
  1258. AA_IP_ENTRY_RESOLVED);
  1259. pIpEntry->NextMultiSeq = AA_MARS_INITIAL_Y;
  1260. //
  1261. // Now close the PMP VC for this group, if one exists.
  1262. // If we don't have a VC, start a connection.
  1263. //
  1264. pVc = pIpEntry->pAtmEntry->pVcList;
  1265. AA_RELEASE_IE_LOCK(pIpEntry);
  1266. if (pVc != (PATMARP_VC)NULL)
  1267. {
  1268. AA_ACQUIRE_VC_LOCK(pVc);
  1269. //
  1270. // When the call is closed, we start a new
  1271. // PMP connection, using the migrate list.
  1272. //
  1273. AtmArpCloseCall(pVc);
  1274. }
  1275. else
  1276. {
  1277. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  1278. AtmArpMcUpdateConnection(pAtmEntry);
  1279. //
  1280. // AE Lock is released within the above.
  1281. //
  1282. }
  1283. }
  1284. else
  1285. {
  1286. //
  1287. // Discard this MIGRATE
  1288. //
  1289. AA_RELEASE_IE_LOCK(pIpEntry);
  1290. }
  1291. break;
  1292. }
  1293. while (FALSE);
  1294. //
  1295. // Finally (according to Section 5.1.4.2 of RFC 2022), check
  1296. // if we just had a jump in the MSN.
  1297. //
  1298. if ((SeqDiff != 1) && (SeqDiff != 0))
  1299. {
  1300. AAMCDEBUGP(AAD_INFO,
  1301. ("HandleMigrate: IF 0x%x: Bad seq diff %d, MSN 0x%x, HSN 0x%x\n",
  1302. pInterface, SeqDiff, MarsSeqNumber, HostSeqNumber));
  1303. AtmArpMcRevalidateAll(pInterface);
  1304. }
  1305. }
  1306. VOID
  1307. AtmArpMcHandleJoinOrLeave(
  1308. IN PATMARP_VC pVc,
  1309. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  1310. IN ULONG TotalLength,
  1311. IN PAA_MARS_TLV_LIST pTlvList
  1312. )
  1313. /*++
  1314. Routine Description:
  1315. Process a received MARS_JOIN/MARS_LEAVE message. If this is a copy of a
  1316. message that we had sent, then there are two cases: (1) we are registering with
  1317. MARS, in which case we send MARS_JOINs for all pending Joins (2) we were
  1318. Joining a multicast group, in which case the Join operation is complete.
  1319. If this is not a copy of a MARS_JOIN originated from us, then we check if
  1320. the multicast group being joined is one to which we are sending. If so,
  1321. and if the station joining is not already a member of that group, we add it.
  1322. Arguments:
  1323. pVc - Pointer to our VC structure on which the packet
  1324. arrived.
  1325. pControlHeader - Pointer to the start of the packet contents
  1326. TotalLength - Total length of this packet.
  1327. pTlvList - All TLVs seen in this packet
  1328. Return Value:
  1329. None
  1330. --*/
  1331. {
  1332. PAA_MARS_JOIN_LEAVE_HEADER pJoinHeader;
  1333. PATMARP_INTERFACE pInterface; // IF on which this packet arrived
  1334. ULONG IfState; // State of the interface
  1335. IP_ADDRESS IPAddress;
  1336. PATMARP_IP_ENTRY pIpEntry; // Our entry for the group being joined
  1337. PATMARP_IPMC_ATM_ENTRY pMcAtmEntry;
  1338. PATMARP_ATM_ENTRY pAtmEntry;
  1339. ULONG MarsSeqNumber; // MSN received in this packet
  1340. ULONG HostSeqNumber; // Our MSN
  1341. ULONG SeqDiff; // Difference between MSN and the HSN
  1342. USHORT Flags; // From the JOIN packet
  1343. BOOLEAN bLayer3Group; // Is a Layer 3 explicitly Joining?
  1344. BOOLEAN bCopyBitSet; // Is the COPY bit set?
  1345. BOOLEAN bRegister; // Is this a cluster member registering?
  1346. BOOLEAN bPunched; // Is the Punched bit set?
  1347. PUCHAR pSrcAtmNumber;
  1348. PUCHAR pSrcAtmSubaddress;
  1349. BOOLEAN bIsAtmNumberOurs; // Is the source ATM Number ours?
  1350. ATM_ADDRESSTYPE AtmNumberType;
  1351. ULONG AtmNumberLength;
  1352. ATM_ADDRESSTYPE AtmSubaddressType;
  1353. ULONG AtmSubaddressLength;
  1354. IP_ADDRESS UNALIGNED * pMinIPAddress;
  1355. IP_ADDRESS UNALIGNED * pMaxIPAddress;
  1356. IP_ADDRESS MinIPAddress;
  1357. IP_ADDRESS MaxIPAddress;
  1358. BOOLEAN IsJoin; // Is this a JOIN?
  1359. BOOLEAN ProcessMcSendList = TRUE;
  1360. //
  1361. // Initialize
  1362. //
  1363. pInterface = pVc->pInterface;
  1364. SeqDiff = 0;
  1365. pJoinHeader = (PAA_MARS_JOIN_LEAVE_HEADER)pControlHeader;
  1366. IsJoin = (pJoinHeader->op == NET_SHORT(AA_MARS_OP_TYPE_JOIN));
  1367. //
  1368. // Get the MARS Sequence Number in this message.
  1369. //
  1370. MarsSeqNumber = NET_TO_HOST_LONG(pJoinHeader->msn);
  1371. AA_ACQUIRE_IF_LOCK(pInterface);
  1372. HostSeqNumber = pInterface->HostSeqNumber; // save the old value
  1373. pInterface->HostSeqNumber = MarsSeqNumber; // and update
  1374. IfState = AAMC_IF_STATE(pInterface);
  1375. AA_RELEASE_IF_LOCK(pInterface);
  1376. SeqDiff = MarsSeqNumber - HostSeqNumber;
  1377. //
  1378. // Get all "flag" values:
  1379. //
  1380. Flags = pJoinHeader->flags;
  1381. bLayer3Group = ((Flags & AA_MARS_JL_FLAG_LAYER3_GROUP) != 0);
  1382. bCopyBitSet = ((Flags & AA_MARS_JL_FLAG_COPY) != 0);
  1383. bRegister = ((Flags & AA_MARS_JL_FLAG_REGISTER) != 0);
  1384. bPunched = ((Flags & AA_MARS_JL_FLAG_PUNCHED) != 0);
  1385. //
  1386. // Get at the source ATM number
  1387. //
  1388. pSrcAtmNumber = ((PUCHAR)pJoinHeader +
  1389. sizeof(AA_MARS_JOIN_LEAVE_HEADER));
  1390. AA_PKT_TYPE_LEN_TO_ATM_ADDRESS(
  1391. pJoinHeader->shtl,
  1392. &AtmNumberType,
  1393. &AtmNumberLength);
  1394. //
  1395. // Get at the source ATM subaddress
  1396. //
  1397. pSrcAtmSubaddress = ((PUCHAR)pSrcAtmNumber + AtmNumberLength);
  1398. AA_PKT_TYPE_LEN_TO_ATM_ADDRESS(
  1399. pJoinHeader->sstl,
  1400. &AtmSubaddressType,
  1401. &AtmSubaddressLength);
  1402. bIsAtmNumberOurs = ((AtmNumberType == pInterface->LocalAtmAddress.AddressType) &&
  1403. (AtmNumberLength == pInterface->LocalAtmAddress.NumberOfDigits) &&
  1404. (AA_MEM_CMP(pSrcAtmNumber,
  1405. pInterface->LocalAtmAddress.Address,
  1406. AtmNumberLength) == 0));
  1407. pMinIPAddress = (PIP_ADDRESS)((PUCHAR)pJoinHeader +
  1408. sizeof(AA_MARS_JOIN_LEAVE_HEADER)+
  1409. AtmNumberLength +
  1410. AtmSubaddressLength +
  1411. (pJoinHeader->spln & ~AA_PKT_ATM_ADDRESS_BIT));
  1412. pMaxIPAddress = (PIP_ADDRESS)((PUCHAR)pMinIPAddress +
  1413. (pJoinHeader->tpln & ~AA_PKT_ATM_ADDRESS_BIT));
  1414. AAMCDEBUGP(AAD_LOUD,
  1415. ("Handle %s: Flags 0x%x, OurAtmNum %d, Punch %d, Copy %d, pnum %d, IFState 0x%x\n",
  1416. (IsJoin? "JOIN": "LEAVE"),
  1417. Flags,
  1418. (ULONG)bIsAtmNumberOurs,
  1419. (ULONG)bPunched,
  1420. (ULONG)bCopyBitSet,
  1421. pJoinHeader->pnum,
  1422. AAMC_IF_STATE(pInterface)
  1423. ));
  1424. AAMCDEBUGP(AAD_LOUD,
  1425. ("Handle %s: Min %d.%d.%d.%d, Max %d.%d.%d.%d\n",
  1426. (IsJoin? "JOIN": "LEAVE"),
  1427. ((PUCHAR)pMinIPAddress)[0], ((PUCHAR)pMinIPAddress)[1],
  1428. ((PUCHAR)pMinIPAddress)[2], ((PUCHAR)pMinIPAddress)[3],
  1429. ((PUCHAR)pMaxIPAddress)[0], ((PUCHAR)pMaxIPAddress)[1],
  1430. ((PUCHAR)pMaxIPAddress)[2], ((PUCHAR)pMaxIPAddress)[3]));
  1431. if (bIsAtmNumberOurs && (!bPunched) && bCopyBitSet)
  1432. {
  1433. //
  1434. // Potentially sent by us
  1435. //
  1436. ProcessMcSendList = FALSE; // we may set it back to true -- see below.
  1437. if (IfState == AAMC_IF_STATE_REGISTERING)
  1438. {
  1439. if (IsJoin &&
  1440. bRegister &&
  1441. (pJoinHeader->pnum == 0))
  1442. {
  1443. BOOLEAN WasRunning;
  1444. //
  1445. // Registration complete. Get our Cluster Member ID.
  1446. // We store this in network order so that we can
  1447. // use it to fill packets directly.
  1448. //
  1449. AA_ACQUIRE_IF_LOCK(pInterface);
  1450. pInterface->ClusterMemberId = pJoinHeader->cmi;
  1451. AAMCDEBUGP(AAD_INFO,
  1452. ("==== HandleJoin: pIf 0x%x, registered with MARS, CMI %d!\n",
  1453. pInterface, pInterface->ClusterMemberId));
  1454. AAMC_SET_IF_STATE(pInterface, AAMC_IF_STATE_REGISTERED);
  1455. //
  1456. // Stop the MARS Registration timer.
  1457. //
  1458. WasRunning = AtmArpStopTimer(&(pInterface->McTimer), pInterface);
  1459. AA_ASSERT(WasRunning);
  1460. //
  1461. // Start MARS wait-for-keepalive timer.
  1462. //
  1463. AtmArpStartTimer(
  1464. pInterface,
  1465. &(pInterface->McTimer),
  1466. AtmArpMcMARSKeepAliveTimeout,
  1467. pInterface->MARSKeepAliveTimeout,
  1468. (PVOID)pInterface
  1469. );
  1470. //
  1471. // If we are recovering from a MARS failure,
  1472. // then we need to initiate revalidation of all
  1473. // groups we send to.
  1474. //
  1475. if (!AA_IS_FLAG_SET(pInterface->Flags,
  1476. AAMC_IF_MARS_FAILURE_MASK,
  1477. AAMC_IF_MARS_FAILURE_NONE))
  1478. {
  1479. AA_SET_FLAG(pInterface->Flags,
  1480. AAMC_IF_MARS_FAILURE_MASK,
  1481. AAMC_IF_MARS_FAILURE_NONE);
  1482. SeqDiff = 2; // a dirty way of triggering the above
  1483. }
  1484. //
  1485. // Send any JOINs we have pended waiting for registration
  1486. // to be over.
  1487. //
  1488. // TBDMC: Section 5.4.1 recommends that if we are doing this
  1489. // after a failure recovery, then a random delay should be
  1490. // inserted between JOINs...
  1491. //
  1492. AtmArpMcSendPendingJoins(pInterface);
  1493. //
  1494. // IF Lock is released within the above.
  1495. //
  1496. }
  1497. //
  1498. // else Discard: we aren't interested in this packet
  1499. //
  1500. }
  1501. else
  1502. {
  1503. //
  1504. // Potentially a Join/Leave sent by us for a multicast group
  1505. //
  1506. if (pJoinHeader->pnum == HOST_TO_NET_SHORT(1))
  1507. {
  1508. //
  1509. // Check if this came on the cluster control vc (or rather, we cheat
  1510. // and simply check if this is an incoming vc) -- if
  1511. // so we want to also process the McSendList to see if
  1512. // we need to add/remove ourselves to any mc ip send entries.
  1513. //
  1514. if (AA_IS_FLAG_SET(
  1515. pVc->Flags,
  1516. AA_VC_OWNER_MASK,
  1517. AA_VC_OWNER_IS_CALLMGR))
  1518. {
  1519. ProcessMcSendList = TRUE;
  1520. }
  1521. //
  1522. // Get the IP address range of group being joined/left.
  1523. //
  1524. IPAddress = *pMinIPAddress;
  1525. AtmArpMcHandleJoinOrLeaveCompletion(
  1526. pInterface,
  1527. IPAddress,
  1528. IPAddress ^ *pMaxIPAddress,
  1529. IsJoin);
  1530. }
  1531. //
  1532. // else Discard: bad pnum
  1533. //
  1534. }
  1535. }
  1536. if (ProcessMcSendList)
  1537. {
  1538. //
  1539. // Not sent by us, or punched, or it was sent by us but it came on the
  1540. // cluster control vc. For each <Min, Max> pair in this message,
  1541. // check if the pair overlaps any of the MC addresses to which
  1542. // we send packets. For each such IP entry, we find the MC ATM
  1543. // Entry corresponding to the host that is joining/leaving,
  1544. // and if necessary, mark it as needing a connection update.
  1545. //
  1546. // Then, we go thru the list of MC IP Entries, and start a
  1547. // connection update on all marked entries.
  1548. //
  1549. BOOLEAN bWorkDone;
  1550. USHORT MinMaxPairs;
  1551. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1552. MinMaxPairs = NET_TO_HOST_SHORT(pJoinHeader->pnum);
  1553. pIpEntry = pInterface->pMcSendList;
  1554. while (MinMaxPairs--)
  1555. {
  1556. MinIPAddress = NET_LONG(*pMinIPAddress);
  1557. MaxIPAddress = NET_LONG(*pMaxIPAddress);
  1558. while (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1559. {
  1560. IPAddress = NET_LONG(pIpEntry->IPAddress);
  1561. if (IPAddress <= MaxIPAddress)
  1562. {
  1563. if (IPAddress >= MinIPAddress)
  1564. {
  1565. //
  1566. // This is an IP Entry that might be affected.
  1567. //
  1568. AA_ACQUIRE_IE_LOCK_DPC(pIpEntry);
  1569. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  1570. do
  1571. {
  1572. BOOLEAN bNeedToUpdateConnection;
  1573. if (pIpEntry->pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  1574. {
  1575. //
  1576. // Skip this because it hasn't been resolved.
  1577. //
  1578. break;
  1579. }
  1580. pAtmEntry = pIpEntry->pAtmEntry;
  1581. if (AA_IS_FLAG_SET(pAtmEntry->Flags,
  1582. AA_ATM_ENTRY_TYPE_MASK,
  1583. AA_ATM_ENTRY_TYPE_UCAST))
  1584. {
  1585. if ((AtmNumberType != pAtmEntry->ATMAddress.AddressType) ||
  1586. (AtmNumberLength != pAtmEntry->ATMAddress.NumberOfDigits) ||
  1587. (AA_MEM_CMP(pSrcAtmNumber,
  1588. pAtmEntry->ATMAddress.Address,
  1589. AtmNumberLength) != 0))
  1590. {
  1591. //
  1592. // Addresses don't match; if this is a new JOIN,
  1593. // then this IP Entry needs updating.
  1594. //
  1595. bNeedToUpdateConnection = (IsJoin);
  1596. }
  1597. else
  1598. {
  1599. bNeedToUpdateConnection = !(IsJoin);
  1600. }
  1601. if (bNeedToUpdateConnection)
  1602. {
  1603. //
  1604. // Mark this entry so that we abort it below.
  1605. //
  1606. AA_SET_FLAG(pIpEntry->Flags,
  1607. AA_IP_ENTRY_STATE_MASK,
  1608. AA_IP_ENTRY_ABORTING);
  1609. }
  1610. break; // end of Unicast ATM Entry case
  1611. }
  1612. //
  1613. // Multicast IP Entry.
  1614. //
  1615. pMcAtmEntry = AtmArpMcLookupAtmMember(
  1616. pIpEntry->pAtmEntry,
  1617. &(pAtmEntry->pMcAtmInfo->pMcAtmEntryList),
  1618. pSrcAtmNumber,
  1619. AtmNumberLength,
  1620. AtmNumberType,
  1621. pSrcAtmSubaddress,
  1622. AtmSubaddressLength,
  1623. IsJoin
  1624. );
  1625. if (pMcAtmEntry != NULL_PATMARP_IPMC_ATM_ENTRY)
  1626. {
  1627. AAMCDEBUGPATMADDR(AAD_EXTRA_LOUD,
  1628. (IsJoin? "Join Addr: ": "Leave Addr"),
  1629. &pMcAtmEntry->ATMAddress);
  1630. if (!IsJoin)
  1631. {
  1632. //
  1633. // Mark this entry so that it will be dropped from
  1634. // our connection to this multicast group.
  1635. //
  1636. if (AA_IS_FLAG_SET(pMcAtmEntry->Flags,
  1637. AA_IPMC_AE_GEN_STATE_MASK,
  1638. AA_IPMC_AE_VALID))
  1639. {
  1640. AA_SET_FLAG(pMcAtmEntry->Flags,
  1641. AA_IPMC_AE_GEN_STATE_MASK,
  1642. AA_IPMC_AE_INVALID);
  1643. bNeedToUpdateConnection = TRUE;
  1644. }
  1645. }
  1646. else
  1647. {
  1648. bNeedToUpdateConnection =
  1649. (AA_IS_FLAG_SET(pMcAtmEntry->Flags,
  1650. AA_IPMC_AE_CONN_STATE_MASK,
  1651. AA_IPMC_AE_CONN_DISCONNECTED));
  1652. }
  1653. if (bNeedToUpdateConnection)
  1654. {
  1655. //
  1656. // Mark this ATM MC entry as wanting a connection
  1657. // update.
  1658. //
  1659. pIpEntry->pAtmEntry->pMcAtmInfo->Flags |=
  1660. AA_IPMC_AI_WANT_UPDATE;
  1661. }
  1662. }
  1663. break;
  1664. }
  1665. while (FALSE);
  1666. AA_RELEASE_IE_LOCK_DPC(pIpEntry);
  1667. }
  1668. pIpEntry = pIpEntry->pNextMcEntry;
  1669. }
  1670. else
  1671. {
  1672. //
  1673. // This IP Address lies beyond this <Min, Max> pair.
  1674. // Go to the next pair.
  1675. //
  1676. break;
  1677. }
  1678. }
  1679. if (pIpEntry == NULL_PATMARP_IP_ENTRY)
  1680. {
  1681. break;
  1682. }
  1683. pMinIPAddress = (PIP_ADDRESS)((PUCHAR)pMaxIPAddress +
  1684. (pJoinHeader->tpln & ~AA_PKT_ATM_ADDRESS_BIT));
  1685. } // while loop processing all <Min, Max> pairs
  1686. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1687. //
  1688. // Now, for each ATM MC entry that we marked in the previous
  1689. // step, start a connection update.
  1690. //
  1691. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1692. //
  1693. // We keep running through the McSendList, stopping when no work is done.
  1694. // This is because in order to "do work" we must release the table lock,
  1695. // in which case the McSendList may be modified by someone else.
  1696. //
  1697. do
  1698. {
  1699. bWorkDone = FALSE;
  1700. for (pIpEntry = pInterface->pMcSendList;
  1701. pIpEntry != NULL_PATMARP_IP_ENTRY;
  1702. pIpEntry = pIpEntry->pNextMcEntry)
  1703. {
  1704. ULONG McAiFlags;
  1705. pAtmEntry = pIpEntry->pAtmEntry;
  1706. if (pAtmEntry == NULL_PATMARP_ATM_ENTRY)
  1707. {
  1708. //
  1709. // Not yet resolved. Skip this one.
  1710. //
  1711. continue;
  1712. }
  1713. if (AA_IS_FLAG_SET(pIpEntry->Flags,
  1714. AA_IP_ENTRY_STATE_MASK,
  1715. AA_IP_ENTRY_ABORTING))
  1716. {
  1717. //
  1718. // Must be a unicast entry that we marked above.
  1719. //
  1720. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1721. bWorkDone = TRUE;
  1722. AA_ACQUIRE_IE_LOCK(pIpEntry);
  1723. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  1724. AtmArpAbortIPEntry(pIpEntry);
  1725. //
  1726. // IE lock is released within the above.
  1727. //
  1728. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1729. break;
  1730. }
  1731. //
  1732. // If this is a unicast ATM Entry, there is nothing
  1733. // more to be done. If this needed revalidation,
  1734. // we would have aborted it above.
  1735. //
  1736. if (AA_IS_FLAG_SET(pAtmEntry->Flags,
  1737. AA_ATM_ENTRY_TYPE_MASK,
  1738. AA_ATM_ENTRY_TYPE_UCAST))
  1739. {
  1740. continue;
  1741. }
  1742. AA_ASSERT(pAtmEntry->pMcAtmInfo != NULL_PATMARP_IPMC_ATM_INFO);
  1743. McAiFlags = pAtmEntry->pMcAtmInfo->Flags;
  1744. if (McAiFlags & AA_IPMC_AI_BEING_UPDATED)
  1745. {
  1746. //
  1747. // Nothing to be done on this one.
  1748. //
  1749. continue;
  1750. }
  1751. if (McAiFlags & AA_IPMC_AI_WANT_UPDATE)
  1752. {
  1753. //
  1754. // Needs a connection update.
  1755. //
  1756. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1757. bWorkDone = TRUE;
  1758. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  1759. AtmArpMcUpdateConnection(pAtmEntry);
  1760. //
  1761. // AE Lock is released within the above.
  1762. //
  1763. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1764. break;
  1765. }
  1766. }
  1767. }
  1768. while (bWorkDone);
  1769. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1770. } // else (Packet not a copy of ours)
  1771. //
  1772. // Finally (according to Section 5.1.4.2 of RFC 2022), check
  1773. // if we just had a jump in the MSN.
  1774. //
  1775. if ((SeqDiff != 1) && (SeqDiff != 0))
  1776. {
  1777. AAMCDEBUGP(AAD_INFO,
  1778. ("HandleJoin+Leave: IF 0x%x: Bad seq diff %d, MSN 0x%x, HSN 0x%x\n",
  1779. pInterface, SeqDiff, MarsSeqNumber, HostSeqNumber));
  1780. AtmArpMcRevalidateAll(pInterface);
  1781. }
  1782. }
  1783. VOID
  1784. AtmArpMcHandleNak(
  1785. IN PATMARP_VC pVc,
  1786. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  1787. IN ULONG TotalLength,
  1788. IN PAA_MARS_TLV_LIST pTlvList
  1789. )
  1790. /*++
  1791. Routine Description:
  1792. Process a received MARS_NAK message. We mark the IP Entry corresponding
  1793. to the IP Address being resolved as having seen a NAK. This is so that
  1794. we don't send another MARS Request for this IP address too soon. We also
  1795. start a timer at the end of which we unmark this IP Entry, so that
  1796. we may try to resolve it again.
  1797. Arguments:
  1798. pVc - Pointer to our VC structure on which the packet
  1799. arrived.
  1800. pControlHeader - Pointer to the start of the packet contents
  1801. TotalLength - Total length of this packet.
  1802. IN PAA_MARS_TLV_LIST pTlvList
  1803. Return Value:
  1804. None
  1805. --*/
  1806. {
  1807. PATMARP_INTERFACE pInterface;
  1808. PAA_MARS_REQ_NAK_HEADER pNakHeader;
  1809. PATMARP_IP_ENTRY pIpEntry; // Entry for IP address being resolved
  1810. PATMARP_ATM_ENTRY pAtmEntry; // Corresponding ATM Entry
  1811. IP_ADDRESS IPAddress; // the address being queried
  1812. BOOLEAN bWasRunning; // Was a timer running?
  1813. PNDIS_PACKET PacketList; // Packets queued for sending
  1814. ULONG rc;
  1815. //
  1816. // Initialize
  1817. //
  1818. pInterface = pVc->pInterface;
  1819. pNakHeader = (PAA_MARS_REQ_NAK_HEADER)pControlHeader;
  1820. do
  1821. {
  1822. //
  1823. // Get the group address being responded to.
  1824. //
  1825. IPAddress = *(IP_ADDRESS UNALIGNED *)(
  1826. (PUCHAR)pNakHeader +
  1827. sizeof(AA_MARS_REQ_NAK_HEADER) +
  1828. (pNakHeader->shtl & ~AA_PKT_ATM_ADDRESS_BIT) +
  1829. (pNakHeader->sstl & ~AA_PKT_ATM_ADDRESS_BIT) +
  1830. (pNakHeader->spln)
  1831. );
  1832. AAMCDEBUGP(AAD_LOUD,
  1833. ("McHandleNak: 0x%x, IP %d.%d.%d.%d\n",
  1834. pNakHeader,
  1835. ((PUCHAR)&IPAddress)[0],
  1836. ((PUCHAR)&IPAddress)[1],
  1837. ((PUCHAR)&IPAddress)[2],
  1838. ((PUCHAR)&IPAddress)[3]));
  1839. //
  1840. // Get the IP Entry for this address.
  1841. //
  1842. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1843. pIpEntry = AtmArpSearchForIPAddress(
  1844. pInterface,
  1845. &IPAddress,
  1846. IE_REFTYPE_TMP,
  1847. TRUE, // this is a multicast/broadcast address
  1848. FALSE // don't create a new entry if the address isn't found
  1849. );
  1850. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1851. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1852. {
  1853. //
  1854. // AtmArpSearchForIPAddress addreffs pIpEntry for us ...
  1855. //
  1856. ULONG IeRefCount;
  1857. AA_ACQUIRE_IE_LOCK(pIpEntry);
  1858. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  1859. IeRefCount = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TMP);
  1860. if (IeRefCount == 0)
  1861. {
  1862. // Oops, IP address has gone away...
  1863. pIpEntry = NULL_PATMARP_IP_ENTRY;
  1864. }
  1865. }
  1866. if (pIpEntry == NULL_PATMARP_IP_ENTRY)
  1867. {
  1868. AAMCDEBUGP(AAD_INFO, ("McHandleNak: No IP Entry for %d.%d.%d.%d\n",
  1869. ((PUCHAR)&IPAddress)[0],
  1870. ((PUCHAR)&IPAddress)[1],
  1871. ((PUCHAR)&IPAddress)[2],
  1872. ((PUCHAR)&IPAddress)[3]));
  1873. break;
  1874. }
  1875. bWasRunning = AtmArpStopTimer(&(pIpEntry->Timer), pInterface);
  1876. if (bWasRunning)
  1877. {
  1878. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  1879. AA_ASSERT(rc != 0);
  1880. }
  1881. else
  1882. {
  1883. AAMCDEBUGP(AAD_WARNING,
  1884. ("McHandleNak: 0x%x, IP %d.%d.%d.%d NO TIMER RUNNING\n",
  1885. pNakHeader,
  1886. ((PUCHAR)&IPAddress)[0],
  1887. ((PUCHAR)&IPAddress)[1],
  1888. ((PUCHAR)&IPAddress)[2],
  1889. ((PUCHAR)&IPAddress)[3]));
  1890. }
  1891. //
  1892. // Take out all packets queued on this entry
  1893. //
  1894. PacketList = pIpEntry->PacketList;
  1895. pIpEntry->PacketList = (PNDIS_PACKET)NULL;
  1896. //
  1897. // Mark this IP Entry as being resolved, but seen NAK.
  1898. //
  1899. AA_SET_FLAG(pIpEntry->Flags,
  1900. AA_IP_ENTRY_MC_RESOLVE_MASK,
  1901. AA_IP_ENTRY_MC_RESOLVED);
  1902. AA_SET_FLAG(pIpEntry->Flags,
  1903. AA_IP_ENTRY_MC_VALIDATE_MASK,
  1904. AA_IP_ENTRY_MC_NO_REVALIDATION);
  1905. AA_SET_FLAG(pIpEntry->Flags,
  1906. AA_IP_ENTRY_STATE_MASK,
  1907. AA_IP_ENTRY_SEEN_NAK);
  1908. AtmArpStartTimer(
  1909. pInterface,
  1910. &(pIpEntry->Timer),
  1911. AtmArpNakDelayTimeout,
  1912. pInterface->MinWaitAfterNak,
  1913. (PVOID)pIpEntry // Context
  1914. );
  1915. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  1916. AA_RELEASE_IE_LOCK(pIpEntry);
  1917. //
  1918. // Free any packets that were queued up.
  1919. //
  1920. if (PacketList != (PNDIS_PACKET)NULL)
  1921. {
  1922. AtmArpFreeSendPackets(
  1923. pInterface,
  1924. PacketList,
  1925. FALSE // No headers on these
  1926. );
  1927. }
  1928. break;
  1929. }
  1930. while (FALSE);
  1931. }
  1932. VOID
  1933. AtmArpMcHandleGroupListReply(
  1934. IN PATMARP_VC pVc,
  1935. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  1936. IN ULONG TotalLength,
  1937. IN PAA_MARS_TLV_LIST pTlvList
  1938. )
  1939. /*++
  1940. Routine Description:
  1941. Process a received MARS_GROUPLIST_REPLY message.
  1942. Arguments:
  1943. pVc - Pointer to our VC structure on which the packet
  1944. arrived.
  1945. pControlHeader - Pointer to the start of the packet contents
  1946. TotalLength - Total length of this packet.
  1947. IN PAA_MARS_TLV_LIST pTlvList
  1948. Return Value:
  1949. None
  1950. --*/
  1951. {
  1952. AAMCDEBUGP(AAD_WARNING, ("GroupListReply unexpected\n"));
  1953. AA_ASSERT(FALSE);
  1954. }
  1955. VOID
  1956. AtmArpMcHandleRedirectMap(
  1957. IN PATMARP_VC pVc,
  1958. IN PAA_MARS_PKT_FIXED_HEADER pControlHeader,
  1959. IN ULONG TotalLength,
  1960. IN PAA_MARS_TLV_LIST pTlvList
  1961. )
  1962. /*++
  1963. Routine Description:
  1964. Process a received MARS_REDIRECT_MAP message. For now, we simply
  1965. refresh the MARS Keepalive timer.
  1966. TBDMC: Parse fully, and update MARS list, and migrate if necessary.
  1967. Arguments:
  1968. pVc - Pointer to our VC structure on which the packet
  1969. arrived.
  1970. pControlHeader - Pointer to the start of the packet contents
  1971. TotalLength - Total length of this packet.
  1972. IN PAA_MARS_TLV_LIST pTlvList
  1973. Return Value:
  1974. None
  1975. --*/
  1976. {
  1977. PATMARP_INTERFACE pInterface;
  1978. PAA_MARS_REDIRECT_MAP_HEADER pRedirectHeader;
  1979. ULONG MarsSeqNumber;
  1980. ULONG HostSeqNumber;
  1981. ULONG SeqDiff;
  1982. //
  1983. // Initialize
  1984. //
  1985. pInterface = pVc->pInterface;
  1986. SeqDiff = 0;
  1987. AAMCDEBUGP(AAD_VERY_LOUD, ("### REDIRECT MAP 0x%x on VC 0x%x, IF 0x%x/0x%x\n",
  1988. pControlHeader, pVc, pInterface, pInterface->Flags));
  1989. pRedirectHeader = (PAA_MARS_REDIRECT_MAP_HEADER)pControlHeader;
  1990. AA_ACQUIRE_IF_LOCK(pInterface);
  1991. if ((AAMC_IF_STATE(pInterface) == AAMC_IF_STATE_REGISTERED) &&
  1992. (AA_IS_FLAG_SET(pInterface->Flags,
  1993. AAMC_IF_MARS_FAILURE_MASK,
  1994. AAMC_IF_MARS_FAILURE_NONE)))
  1995. {
  1996. //
  1997. // Get the MARS Sequence Number in this message.
  1998. //
  1999. MarsSeqNumber = NET_TO_HOST_LONG(pRedirectHeader->msn);
  2000. HostSeqNumber = pInterface->HostSeqNumber; // save the old value
  2001. pInterface->HostSeqNumber = MarsSeqNumber; // and update
  2002. SeqDiff = MarsSeqNumber - HostSeqNumber;
  2003. //
  2004. // The MC Timer running on the IF must be MARS Keepalive
  2005. //
  2006. AA_ASSERT(pInterface->McTimer.TimeoutHandler == AtmArpMcMARSKeepAliveTimeout);
  2007. AAMCDEBUGP(AAD_EXTRA_LOUD,
  2008. ("Redirect MAP: refreshing keepalive on IF 0x%x, new HSN %d\n",
  2009. pInterface, pInterface->HostSeqNumber));
  2010. AtmArpRefreshTimer(&(pInterface->McTimer));
  2011. }
  2012. AA_RELEASE_IF_LOCK(pInterface);
  2013. //
  2014. // Finally (according to Section 5.1.4.2 of RFC 2022), check
  2015. // if we just had a jump in the MSN.
  2016. //
  2017. if ((SeqDiff != 1) && (SeqDiff != 0))
  2018. {
  2019. AAMCDEBUGP(AAD_INFO,
  2020. ("HandleRedirectMap: IF 0x%x: Bad seq diff %d, MSN 0x%x, HSN 0x%x\n",
  2021. pInterface, SeqDiff, MarsSeqNumber, HostSeqNumber));
  2022. AtmArpMcRevalidateAll(pInterface);
  2023. }
  2024. return;
  2025. }
  2026. #endif // IPMCAST