79 IN UINT8 PrefixLength,
80 IN UINT32 ValidLifetime,
81 IN UINT32 PreferredLifetime,
82 IN IP6_DAD_CALLBACK DadCallback OPTIONAL,
83 IN VOID *Context OPTIONAL
96 if (EFI_ERROR (Status)) {
97 DEBUG ((DEBUG_ERROR,
"%a failed to generate random number: %r\n", __func__, Status));
101 NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);
103 IpSb = Interface->Service;
106 ASSERT (AddressInfo !=
NULL);
110 AddressInfo->ValidLifetime = ValidLifetime;
111 AddressInfo->PreferredLifetime = PreferredLifetime;
113 if (DadCallback !=
NULL) {
114 DadCallback (
TRUE, Ip6Addr, Context);
121 if (AddressInfo ==
NULL) {
122 return EFI_OUT_OF_RESOURCES;
125 AddressInfo->Signature = IP6_ADDR_INFO_SIGNATURE;
126 IP6_COPY_ADDRESS (&AddressInfo->Address, Ip6Addr);
127 AddressInfo->IsAnycast = IsAnycast;
128 AddressInfo->PrefixLength = PrefixLength;
129 AddressInfo->ValidLifetime = ValidLifetime;
130 AddressInfo->PreferredLifetime = PreferredLifetime;
132 if (AddressInfo->PrefixLength == 0) {
137 NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) {
140 if (
NetIp6IsNetEqual (&PrefixEntry->Prefix, &AddressInfo->Address, PrefixEntry->PrefixLength)) {
141 AddressInfo->PrefixLength = PrefixEntry->PrefixLength;
147 if (AddressInfo->PrefixLength == 0) {
152 NET_LIST_FOR_EACH (Entry, &IpSb->AutonomousPrefix) {
155 if (
NetIp6IsNetEqual (&PrefixEntry->Prefix, &AddressInfo->Address, PrefixEntry->PrefixLength)) {
156 AddressInfo->PrefixLength = PrefixEntry->PrefixLength;
162 if (AddressInfo->PrefixLength == 0) {
166 AddressInfo->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;
175 Delay = (UINT64)Random;
176 Delay =
MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS);
180 if (DelayNode ==
NULL) {
182 return EFI_OUT_OF_RESOURCES;
186 DelayNode->Interface = Interface;
187 DelayNode->AddressInfo = AddressInfo;
188 DelayNode->DadCallback = DadCallback;
189 DelayNode->Context = Context;
215 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
218 if (Interface ==
NULL) {
222 Interface->Signature = IP6_INTERFACE_SIGNATURE;
223 Interface->RefCnt = 1;
226 Interface->AddressCount = 0;
227 Interface->Configured =
FALSE;
229 Interface->Service = IpSb;
230 Interface->Controller = IpSb->Controller;
231 Interface->Image = IpSb->Image;
236 Interface->DupAddrDetect = IpSb->Ip6ConfigInstance.DadXmits.DupAddrDetectTransmits;
242 Interface->PromiscRecv =
FALSE;
252 if (Ip6Addr ==
NULL) {
263 IP6_LINK_LOCAL_PREFIX_LENGTH,
264 (UINT32)IP6_INFINIT_LIFETIME,
265 (UINT32)IP6_INFINIT_LIFETIME,
272 if (EFI_ERROR (Status)) {
305 NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);
306 ASSERT (Interface->RefCnt > 0);
313 if (--Interface->RefCnt > 0) {
328 while (!
IsListEmpty (&Interface->DupAddrDetectList)) {
329 Duplicate = NET_LIST_HEAD (&Interface->DupAddrDetectList,
IP6_DAD_ENTRY, Link);
340 Ip6RemoveAddr (Interface->Service, &Interface->AddressList, &Interface->AddressCount,
NULL, 0);
365 IN IP6_FRAME_CALLBACK CallBack,
381 Token->Signature = IP6_LINK_TX_SIGNATURE;
384 Token->IpInstance = IpInstance;
385 Token->CallBack = CallBack;
386 Token->Packet = Packet;
387 Token->Context = Context;
389 IP6_COPY_LINK_ADDRESS (&Token->SrcMac, &Interface->Service->SnpMode.CurrentAddress);
391 MnpToken = &(Token->MnpToken);
392 MnpToken->
Status = EFI_NOT_READY;
394 Status =
gBS->CreateEvent (
402 if (EFI_ERROR (Status)) {
407 MnpTxData = &Token->MnpTxData;
408 MnpToken->Packet.
TxData = MnpTxData;
410 MnpTxData->DestinationAddress = &Token->DstMac;
411 MnpTxData->SourceAddress = &Token->SrcMac;
412 MnpTxData->ProtocolType = IP6_ETHER_PROTO;
413 MnpTxData->DataLength = Packet->TotalSize;
414 MnpTxData->HeaderLength = 0;
416 Count = Packet->BlockOpNum;
419 MnpTxData->FragmentCount = (UINT16)Count;
436 NET_CHECK_SIGNATURE (Token, IP6_LINK_TX_SIGNATURE);
438 gBS->CloseEvent (Token->MnpToken.Event);
459 gBS->SignalEvent (RxData->RecycleEvent);
488 NET_CHECK_SIGNATURE (Token, IP6_LINK_RX_SIGNATURE);
495 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
497 MnpToken = &Token->MnpToken;
498 MnpRxData = MnpToken->Packet.
RxData;
500 if (EFI_ERROR (MnpToken->
Status) || (MnpRxData ==
NULL)) {
501 Token->CallBack (
NULL, MnpToken->
Status, 0, Token->Context);
509 Netfrag.Len = MnpRxData->DataLength;
510 Netfrag.Bulk = MnpRxData->PacketData;
514 if (Packet ==
NULL) {
515 gBS->SignalEvent (MnpRxData->RecycleEvent);
517 Token->CallBack (
NULL, EFI_OUT_OF_RESOURCES, 0, Token->Context);
522 Flag = (MnpRxData->BroadcastFlag ? IP6_LINK_BROADCAST : 0);
523 Flag |= (MnpRxData->MulticastFlag ? IP6_LINK_MULTICAST : 0);
524 Flag |= (MnpRxData->PromiscuousFlag ? IP6_LINK_PROMISC : 0);
526 Token->CallBack (Packet,
EFI_SUCCESS, Flag, Token->Context);
562 IN IP6_FRAME_CALLBACK CallBack,
569 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
571 Token = &IpSb->RecvRequest;
572 Token->CallBack = CallBack;
573 Token->Context = (VOID *)IpSb;
575 Status = IpSb->Mnp->Receive (IpSb->Mnp, &Token->MnpToken);
576 if (EFI_ERROR (Status)) {
599 NET_CHECK_SIGNATURE (Token, IP6_LINK_TX_SIGNATURE);
659 IN IP6_FRAME_CALLBACK CallBack,
670 IpSb = Interface->Service;
671 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
676 if (IpSb->LinkLocalOk) {
677 ASSERT (Interface->Configured);
683 return EFI_OUT_OF_RESOURCES;
686 if (IP6_IS_MULTICAST (NextHop)) {
688 if (EFI_ERROR (Status)) {
698 if (EFI_IP6_EQUAL (&Packet->Ip.Ip6->DestinationAddress, &Packet->Ip.Ip6->SourceAddress)) {
699 IP6_COPY_LINK_ADDRESS (&Token->DstMac, &IpSb->SnpMode.
CurrentAddress);
708 ASSERT (NeighborCache !=
NULL);
710 if (NeighborCache->Interface ==
NULL) {
711 NeighborCache->Interface = Interface;
714 switch (NeighborCache->State) {
717 NeighborCache->Ticks = (UINT32)IP6_GET_TICKS (IP6_DELAY_FIRST_PROBE_TIME);
724 IP6_COPY_LINK_ADDRESS (&Token->DstMac, &NeighborCache->LinkAddress);
736 NET_LIST_FOR_EACH (Entry, &Interface->ArpQues) {
738 if (ArpQue == NeighborCache) {
740 NeighborCache->ArpFree =
TRUE;
751 NeighborCache->ArpFree =
TRUE;
761 Status = IpSb->Mnp->Transmit (IpSb->Mnp, &Token->MnpToken);
762 if (EFI_ERROR (Status)) {
793 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI QueueDpc(IN EFI_TPL DpcTpl, IN EFI_DPC_PROCEDURE DpcProcedure, IN VOID *DpcContext OPTIONAL)
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 Ip6RemoveAddr(IN IP6_SERVICE *IpSb OPTIONAL, IN OUT LIST_ENTRY *AddressList, IN OUT UINT32 *AddressCount, IN EFI_IPv6_ADDRESS *Prefix OPTIONAL, IN UINT8 PrefixLength)
BOOLEAN Ip6IsOneOfSetAddress(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Address, OUT IP6_INTERFACE **Interface OPTIONAL, OUT IP6_ADDRESS_INFO **AddressInfo OPTIONAL)
EFI_IPv6_ADDRESS * Ip6CreateLinkLocalAddr(IN OUT IP6_SERVICE *IpSb)
EFI_STATUS Ip6SetAddress(IN IP6_INTERFACE *Interface, IN EFI_IPv6_ADDRESS *Ip6Addr, IN BOOLEAN IsAnycast, IN UINT8 PrefixLength, IN UINT32 ValidLifetime, IN UINT32 PreferredLifetime, IN IP6_DAD_CALLBACK DadCallback OPTIONAL, IN VOID *Context OPTIONAL)
EFI_STATUS Ip6ReceiveFrame(IN IP6_FRAME_CALLBACK CallBack, IN IP6_SERVICE *IpSb)
IP6_INTERFACE * Ip6CreateInterface(IN IP6_SERVICE *IpSb, IN BOOLEAN LinkLocal)
VOID EFIAPI Ip6OnFrameSentDpc(IN VOID *Context)
VOID EFIAPI Ip6TimerTicking(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI Ip6OnFrameSent(IN EFI_EVENT Event, IN VOID *Context)
IP6_LINK_TX_TOKEN * Ip6CreateLinkTxToken(IN IP6_INTERFACE *Interface, IN IP6_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN IP6_FRAME_CALLBACK CallBack, IN VOID *Context)
VOID EFIAPI Ip6RecycleFrame(IN VOID *Context)
EFI_STATUS Ip6SendFrame(IN IP6_INTERFACE *Interface, IN IP6_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN EFI_IPv6_ADDRESS *NextHop, IN IP6_FRAME_CALLBACK CallBack, IN VOID *Context)
VOID Ip6CleanInterface(IN IP6_INTERFACE *Interface, IN IP6_PROTOCOL *IpInstance OPTIONAL)
VOID EFIAPI Ip6OnFrameReceivedDpc(IN VOID *Context)
VOID EFIAPI Ip6OnFrameReceived(IN EFI_EVENT Event, IN VOID *Context)
BOOLEAN Ip6CancelInstanceFrame(IN IP6_LINK_TX_TOKEN *Frame, IN VOID *Context)
VOID Ip6FreeLinkTxToken(IN IP6_LINK_TX_TOKEN *Token)
VOID Ip6MldTimerTicking(IN IP6_SERVICE *IpSb)
VOID Ip6NdTimerTicking(IN IP6_SERVICE *IpSb)
IP6_NEIGHBOR_ENTRY * Ip6FindNeighborEntry(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Ip6Address)
VOID Ip6CancelFrames(IN IP6_INTERFACE *Interface, IN EFI_STATUS IoStatus, IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, IN VOID *Context OPTIONAL)
#define DEBUG(Expression)
LIST_ENTRY *EFIAPI NetListRemoveHead(IN OUT LIST_ENTRY *Head)
EFI_STATUS EFIAPI NetbufBuildExt(IN NET_BUF *Nbuf, IN OUT NET_FRAGMENT *ExtFragment, IN OUT UINT32 *ExtNum)
BOOLEAN EFIAPI NetIp6IsNetEqual(EFI_IPv6_ADDRESS *Ip1, EFI_IPv6_ADDRESS *Ip2, UINT8 PrefixLength)
NET_BUF *EFIAPI NetbufFromExt(IN NET_FRAGMENT *ExtFragment, IN UINT32 ExtNum, IN UINT32 HeadSpace, IN UINT32 HeadLen, IN NET_VECTOR_EXT_FREE ExtFree, IN VOID *Arg OPTIONAL)
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT32 DelayTime
in tick per 50 milliseconds
EFI_MANAGED_NETWORK_RECEIVE_DATA * RxData
EFI_MANAGED_NETWORK_TRANSMIT_DATA * TxData
EFI_MAC_ADDRESS CurrentAddress