31 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
32 ASSERT (MulticastAddr !=
NULL && IP6_IS_MULTICAST (MulticastAddr));
37 Entry->DelayTimer = DelayTimer;
38 Entry->SendByUs =
FALSE;
39 IP6_COPY_ADDRESS (&Entry->Address, MulticastAddr);
64 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
65 ASSERT (MulticastAddr !=
NULL && IP6_IS_MULTICAST (MulticastAddr));
67 NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) {
69 if (EFI_IP6_EQUAL (MulticastAddr, &Group->Address)) {
101 NET_LIST_FOR_EACH (Entry, &MldCtrl->Groups) {
141 UINT16 PseudoChecksum;
143 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
144 ASSERT (MulticastAddr !=
NULL && IP6_IS_MULTICAST (MulticastAddr));
153 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
155 PayloadLen = (UINT16)(OptionLen +
sizeof (
IP6_MLD_HEAD));
157 if (Packet ==
NULL) {
158 return EFI_OUT_OF_RESOURCES;
168 Head.PayloadLength = HTONS (PayloadLen);
169 Head.NextHeader = IP6_HOP_BY_HOP;
171 IP6_COPY_ADDRESS (&Head.DestinationAddress, MulticastAddr);
176 IP6_COPY_ADDRESS (&Head.SourceAddress, &IpSb->LinkLocalAddr);
184 ASSERT (Options !=
NULL);
186 if (EFI_ERROR (Status)) {
196 ASSERT (MldHead !=
NULL);
198 MldHead->Head.Type = ICMP_V6_LISTENER_REPORT;
199 MldHead->Head.Code = 0;
200 IP6_COPY_ADDRESS (&MldHead->Group, MulticastAddr);
205 &Head.DestinationAddress,
210 MldHead->Head.Checksum = (UINT16) ~
NetAddChecksum (HeadChecksum, PseudoChecksum);
245 UINT16 PseudoChecksum;
247 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
248 ASSERT (MulticastAddr !=
NULL && IP6_IS_MULTICAST (MulticastAddr));
257 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
259 PayloadLen = (UINT16)(OptionLen +
sizeof (
IP6_MLD_HEAD));
261 if (Packet ==
NULL) {
262 return EFI_OUT_OF_RESOURCES;
270 Head.PayloadLength = HTONS (PayloadLen);
271 Head.NextHeader = IP6_HOP_BY_HOP;
277 IP6_COPY_ADDRESS (&Head.SourceAddress, &IpSb->LinkLocalAddr);
280 IP6_COPY_ADDRESS (&Head.DestinationAddress, &Destination);
288 ASSERT (Options !=
NULL);
290 if (EFI_ERROR (Status)) {
300 ASSERT (MldHead !=
NULL);
302 MldHead->Head.Type = ICMP_V6_LISTENER_DONE;
303 MldHead->Head.Code = 0;
304 IP6_COPY_ADDRESS (&MldHead->Group, MulticastAddr);
309 &Head.DestinationAddress,
314 MldHead->Head.Checksum = (UINT16) ~
NetAddChecksum (HeadChecksum, PseudoChecksum);
352 return EFI_OUT_OF_RESOURCES;
356 if (EFI_ERROR (Status)) {
363 Status = IpSb->Mnp->Groups (IpSb->Mnp,
TRUE, &Group->Mac);
364 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
397 NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE);
398 ASSERT (Group !=
NULL && IP6_IS_MULTICAST (Group));
400 IpInstance->GroupCount++;
403 if (GroupList ==
NULL) {
404 return EFI_OUT_OF_RESOURCES;
407 if (IpInstance->GroupCount > 1) {
408 ASSERT (IpInstance->GroupList !=
NULL);
412 IpInstance->GroupList,
419 IP6_COPY_ADDRESS (GroupList + (IpInstance->GroupCount - 1), Group);
421 IpInstance->GroupList = GroupList;
447 Count = IpInstance->GroupCount;
449 for (Index = 0; Index < Count; Index++) {
450 if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, Group)) {
455 if (Index == Count) {
456 return EFI_NOT_FOUND;
459 while (Index < Count - 1) {
460 IP6_COPY_ADDRESS (IpInstance->GroupList + Index, IpInstance->GroupList + Index + 1);
464 ASSERT (IpInstance->GroupCount > 0);
465 IpInstance->GroupCount--;
504 return EFI_OUT_OF_RESOURCES;
507 Group->SendByUs =
TRUE;
510 if (EFI_ERROR (Status)) {
514 Status = IpSb->Mnp->Groups (IpSb->Mnp,
TRUE, &Group->Mac);
515 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
523 if (EFI_ERROR (Status)) {
557 return EFI_NOT_FOUND;
564 if ((Group->RefCnt > 0) && (--Group->RefCnt > 0)) {
573 if (
Ip6FindMac (&IpSb->MldCtrl, &Group->Mac) == 1) {
574 Status = IpSb->Mnp->Groups (IpSb->Mnp,
FALSE, &Group->Mac);
575 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
583 if (Group->SendByUs) {
585 if (EFI_ERROR (Status)) {
624 IpSb = IpInstance->Service;
627 ASSERT (GroupAddress !=
NULL);
629 for (Index = 0; Index < IpInstance->GroupCount; Index++) {
630 if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, GroupAddress)) {
631 return EFI_ALREADY_STARTED;
635 Status =
Ip6JoinGroup (IpSb, IpInstance->Interface, GroupAddress);
636 if (!EFI_ERROR (Status)) {
646 for (Index = IpInstance->GroupCount; Index > 0; Index--) {
647 Group = IpInstance->GroupList + (Index - 1);
649 if ((GroupAddress ==
NULL) || EFI_IP6_EQUAL (Group, GroupAddress)) {
651 if (EFI_ERROR (Status)) {
657 if (IpInstance->GroupCount == 0) {
660 IpInstance->GroupList =
NULL;
663 if (GroupAddress !=
NULL) {
694 IN UINT16 MaxRespDelay,
704 if (EFI_ERROR (Status)) {
705 DEBUG ((DEBUG_ERROR,
"%a failed to generate random number: %r\n", __func__, Status));
713 if (MaxRespDelay == 0) {
714 Group->DelayTimer = 0;
718 Delay = (UINT32)(MaxRespDelay / 1000);
725 if ((Group->DelayTimer == 0) || (Delay < Group->DelayTimer)) {
726 Group->DelayTimer = Delay / 4294967295UL * Random;
758 Status = EFI_INVALID_PARAMETER;
767 if ((Head->HopLimit != 1) || !IP6_IS_MULTICAST (&Head->DestinationAddress)) {
775 MldPacket.MaxRespDelay = NTOHS (MldPacket.MaxRespDelay);
778 if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &AllNodes)) {
782 if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &MldPacket.Group)) {
797 MldPacket.MaxRespDelay,
807 NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) {
810 if (EFI_ERROR (Status)) {
845 Status = EFI_INVALID_PARAMETER;
854 if ((Head->HopLimit != 1) || !IP6_IS_MULTICAST (&Head->DestinationAddress)) {
862 if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &MldPacket.Group)) {
875 if (!Group->SendByUs) {
876 Group->DelayTimer = 0;
904 NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) {
906 if ((Group->DelayTimer > 0) && (--Group->DelayTimer == 0)) {
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS Ip6GetMulticastMac(IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, IN EFI_IPv6_ADDRESS *Multicast, OUT EFI_MAC_ADDRESS *Mac)
EFI_STATUS Ip6SetToAllNodeMulticast(IN BOOLEAN Router, IN UINT8 Scope, OUT EFI_IPv6_ADDRESS *Ip6Addr)
EFI_STATUS Ip6LeaveGroup(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Address)
EFI_STATUS Ip6UpdateDelayTimer(IN IP6_SERVICE *IpSb, IN UINT16 MaxRespDelay, IN EFI_IPv6_ADDRESS *MulticastAddr, IN OUT IP6_MLD_GROUP *Group)
IP6_MLD_GROUP * Ip6CreateMldEntry(IN OUT IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *MulticastAddr, IN UINT32 DelayTimer)
EFI_STATUS Ip6SendMldDone(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *MulticastAddr)
EFI_STATUS Ip6ProcessMldReport(IN IP6_SERVICE *IpSb, IN EFI_IP6_HEADER *Head, IN NET_BUF *Packet)
EFI_STATUS Ip6InitMld(IN IP6_SERVICE *IpSb)
EFI_STATUS Ip6SendMldReport(IN IP6_SERVICE *IpSb, IN IP6_INTERFACE *Interface OPTIONAL, IN EFI_IPv6_ADDRESS *MulticastAddr)
EFI_STATUS Ip6Groups(IN IP6_PROTOCOL *IpInstance, IN BOOLEAN JoinFlag, IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL)
IP6_MLD_GROUP * Ip6FindMldEntry(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *MulticastAddr)
INTN Ip6FindMac(IN IP6_MLD_SERVICE_DATA *MldCtrl, IN EFI_MAC_ADDRESS *Mac)
VOID Ip6MldTimerTicking(IN IP6_SERVICE *IpSb)
EFI_STATUS Ip6ProcessMldQuery(IN IP6_SERVICE *IpSb, IN EFI_IP6_HEADER *Head, IN NET_BUF *Packet)
EFI_STATUS Ip6JoinGroup(IN IP6_SERVICE *IpSb, IN IP6_INTERFACE *Interface, IN EFI_IPv6_ADDRESS *Address)
EFI_STATUS Ip6CombineGroups(IN OUT IP6_PROTOCOL *IpInstance, IN EFI_IPv6_ADDRESS *Group)
EFI_STATUS Ip6RemoveGroup(IN OUT IP6_PROTOCOL *IpInstance, IN EFI_IPv6_ADDRESS *Group)
EFI_STATUS Ip6FillHopByHop(OUT UINT8 *Buffer, IN OUT UINTN *BufferLen, IN UINT8 NextHeader)
EFI_STATUS Ip6Output(IN IP6_SERVICE *IpSb, IN IP6_INTERFACE *Interface OPTIONAL, IN IP6_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN EFI_IP6_HEADER *Head, IN UINT8 *ExtHdrs, IN UINT32 ExtHdrsLen, IN IP6_FRAME_CALLBACK Callback, IN VOID *Context)
VOID Ip6SysPacketSent(NET_BUF *Packet, EFI_STATUS IoStatus, UINT32 LinkFlag, VOID *Context)
#define DEBUG(Expression)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
VOID EFIAPI NetbufReserve(IN OUT NET_BUF *Nbuf, IN UINT32 Len)
UINT16 EFIAPI NetIp6PseudoHeadChecksum(IN EFI_IPv6_ADDRESS *Src, IN EFI_IPv6_ADDRESS *Dst, IN UINT8 NextHeader, IN UINT32 Len)
UINT16 EFIAPI NetblockChecksum(IN UINT8 *Bulk, IN UINT32 Len)
UINT32 EFIAPI NetbufCopy(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT8 *Dest)
BOOLEAN EFIAPI NetIp6IsLinkLocalAddr(IN EFI_IPv6_ADDRESS *Ip6)
UINT16 EFIAPI NetAddChecksum(IN UINT16 Checksum1, IN UINT16 Checksum2)
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI Exit(IN EFI_STATUS Status)