123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848 |
- /** @file
- Contains all EFI_UDP6_PROTOCOL interfaces.
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "Udp6Impl.h"
- EFI_UDP6_PROTOCOL mUdp6Protocol = {
- Udp6GetModeData,
- Udp6Configure,
- Udp6Groups,
- Udp6Transmit,
- Udp6Receive,
- Udp6Cancel,
- Udp6Poll
- };
- /**
- This function copies the current operational settings of this EFI UDPv6 Protocol
- instance into user-supplied buffers. This function is used optionally to retrieve
- the operational mode data of underlying networks or drivers.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @param[out] Udp6ConfigData The buffer in which the current UDP configuration
- data is returned. This parameter is optional and
- may be NULL.
- @param[out] Ip6ModeData The buffer in which the current EFI IPv6 Protocol
- mode data is returned. This parameter is optional
- and may be NULL.
- @param[out] MnpConfigData The buffer in which the current managed network
- configuration data is returned. This parameter is
- optional and may be NULL.
- @param[out] SnpModeData The buffer in which the simple network mode data
- is returned. This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The mode data was read.
- @retval EFI_NOT_STARTED When Udp6ConfigData is queried, no configuration
- data is available because this instance has not
- been started.
- @retval EFI_INVALID_PARAMETER This is NULL.
- **/
- EFI_STATUS
- EFIAPI
- Udp6GetModeData (
- IN EFI_UDP6_PROTOCOL *This,
- OUT EFI_UDP6_CONFIG_DATA *Udp6ConfigData OPTIONAL,
- OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL,
- OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
- OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
- )
- {
- UDP6_INSTANCE_DATA *Instance;
- EFI_IP6_PROTOCOL *Ip;
- EFI_TPL OldTpl;
- EFI_STATUS Status;
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- if (!Instance->Configured && (Udp6ConfigData != NULL)) {
- return EFI_NOT_STARTED;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- if (Udp6ConfigData != NULL) {
- //
- // Set the Udp6ConfigData.
- //
- CopyMem (Udp6ConfigData, &Instance->ConfigData, sizeof (EFI_UDP6_CONFIG_DATA));
- }
- Ip = Instance->IpInfo->Ip.Ip6;
- //
- // Get the underlying Ip6ModeData, MnpConfigData and SnpModeData.
- //
- Status = Ip->GetModeData (Ip, Ip6ModeData, MnpConfigData, SnpModeData);
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- This function is used to do the following:
- Initialize and start this instance of the EFI UDPv6 Protocol.
- Change the filtering rules and operational parameters.
- Reset this instance of the EFI UDPv6 Protocol.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @param[in] UdpConfigData Pointer to the buffer to set the configuration
- data. This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The configuration settings were set, changed, or
- reset successfully.
- @retval EFI_NO_MAPPING When the UdpConfigData.UseAnyStationAddress is set
- to true and there is no address available for the IP6
- driver to bind a source address to this instance.
- @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
- This is NULL.
- UdpConfigData.StationAddress is not a valid
- unicast IPv6 address.
- UdpConfigData.RemoteAddress is not a valid unicast
- IPv6 address if it is not zero.
- @retval EFI_ALREADY_STARTED The EFI UDPv6 Protocol instance is already
- started/configured and must be stopped/reset
- before it can be reconfigured. Only TrafficClass,
- HopLimit, ReceiveTimeout, and TransmitTimeout can
- be reconfigured without stopping the current
- instance of the EFI UDPv6 Protocol.
- @retval EFI_ACCESS_DENIED UdpConfigData.AllowDuplicatePort is FALSE and
- UdpConfigData.StationPort is already used by another
- instance.
- @retval EFI_OUT_OF_RESOURCES The EFI UDPv6 Protocol driver cannot allocate
- memory for this EFI UDPv6 Protocol instance.
- @retval EFI_DEVICE_ERROR An unexpected network or system error occurred, and
- this instance was not opened.
- **/
- EFI_STATUS
- EFIAPI
- Udp6Configure (
- IN EFI_UDP6_PROTOCOL *This,
- IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL
- )
- {
- EFI_STATUS Status;
- UDP6_INSTANCE_DATA *Instance;
- UDP6_SERVICE_DATA *Udp6Service;
- EFI_TPL OldTpl;
- EFI_IPv6_ADDRESS StationAddress;
- EFI_IPv6_ADDRESS RemoteAddress;
- EFI_IP6_CONFIG_DATA Ip6ConfigData;
- EFI_IPv6_ADDRESS LocalAddr;
- EFI_IPv6_ADDRESS RemoteAddr;
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- if (!Instance->Configured && (UdpConfigData == NULL)) {
- return EFI_SUCCESS;
- }
- Udp6Service = Instance->Udp6Service;
- Status = EFI_SUCCESS;
- ASSERT (Udp6Service != NULL);
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- if (UdpConfigData != NULL) {
- IP6_COPY_ADDRESS (&StationAddress, &UdpConfigData->StationAddress);
- IP6_COPY_ADDRESS (&RemoteAddress, &UdpConfigData->RemoteAddress);
- if ((!NetIp6IsUnspecifiedAddr (&StationAddress) && !NetIp6IsValidUnicast (&StationAddress)) ||
- (!NetIp6IsUnspecifiedAddr (&RemoteAddress) && !NetIp6IsValidUnicast (&RemoteAddress))
- )
- {
- //
- // If not use default address, and StationAddress is not a valid unicast
- // if it is not IPv6 address or RemoteAddress is not a valid unicast IPv6
- // address if it is not 0.
- //
- Status = EFI_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- if (Instance->Configured) {
- //
- // The instance is already configured, try to do the re-configuration.
- //
- if (!Udp6IsReconfigurable (&Instance->ConfigData, UdpConfigData)) {
- //
- // If the new configuration data wants to change some unreconfigurable
- // settings, return EFI_ALREADY_STARTED.
- //
- Status = EFI_ALREADY_STARTED;
- goto ON_EXIT;
- }
- //
- // Save the reconfigurable parameters.
- //
- Instance->ConfigData.TrafficClass = UdpConfigData->TrafficClass;
- Instance->ConfigData.HopLimit = UdpConfigData->HopLimit;
- Instance->ConfigData.ReceiveTimeout = UdpConfigData->ReceiveTimeout;
- Instance->ConfigData.TransmitTimeout = UdpConfigData->TransmitTimeout;
- } else {
- //
- // Construct the Ip configuration data from the UdpConfigData.
- //
- Udp6BuildIp6ConfigData (UdpConfigData, &Ip6ConfigData);
- //
- // Configure the Ip instance wrapped in the IpInfo.
- //
- Status = IpIoConfigIp (Instance->IpInfo, &Ip6ConfigData);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_NO_MAPPING) {
- Instance->IsNoMapping = TRUE;
- }
- goto ON_EXIT;
- }
- Instance->IsNoMapping = FALSE;
- //
- // Save the configuration data.
- //
- CopyMem (
- &Instance->ConfigData,
- UdpConfigData,
- sizeof (EFI_UDP6_CONFIG_DATA)
- );
- IP6_COPY_ADDRESS (&Instance->ConfigData.StationAddress, &Ip6ConfigData.StationAddress);
- //
- // Try to allocate the required port resource.
- //
- Status = Udp6Bind (&Udp6Service->ChildrenList, &Instance->ConfigData);
- if (EFI_ERROR (Status)) {
- //
- // Reset the ip instance if bind fails.
- //
- IpIoConfigIp (Instance->IpInfo, NULL);
- goto ON_EXIT;
- }
- //
- // Pre calculate the checksum for the pseudo head, ignore the UDP length first.
- //
- IP6_COPY_ADDRESS (&LocalAddr, &Instance->ConfigData.StationAddress);
- IP6_COPY_ADDRESS (&RemoteAddr, &Instance->ConfigData.RemoteAddress);
- Instance->HeadSum = NetIp6PseudoHeadChecksum (
- &LocalAddr,
- &RemoteAddr,
- EFI_IP_PROTO_UDP,
- 0
- );
- Instance->Configured = TRUE;
- }
- } else {
- //
- // UdpConfigData is NULL, reset the instance.
- //
- Instance->Configured = FALSE;
- Instance->IsNoMapping = FALSE;
- //
- // Reset the Ip instance wrapped in the IpInfo.
- //
- IpIoConfigIp (Instance->IpInfo, NULL);
- //
- // Cancel all the user tokens.
- //
- Instance->Udp6Proto.Cancel (&Instance->Udp6Proto, NULL);
- //
- // Remove the buffered RxData for this instance.
- //
- Udp6FlushRcvdDgram (Instance);
- ASSERT (IsListEmpty (&Instance->DeliveredDgramQue));
- }
- ON_EXIT:
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- This function is used to enable and disable the multicast group filtering.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @param[in] JoinFlag Set to TRUE to join a multicast group. Set to
- FALSE to leave one or all multicast groups.
- @param[in] MulticastAddress Pointer to multicast group address to join or
- leave. This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval EFI_NOT_STARTED The EFI UDPv6 Protocol instance has not been
- started.
- @retval EFI_OUT_OF_RESOURCES Could not allocate resources to join the group.
- @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
- This is NULL.
- JoinFlag is TRUE and MulticastAddress is NULL.
- JoinFlag is TRUE and *MulticastAddress is not a
- valid multicast address.
- @retval EFI_ALREADY_STARTED The group address is already in the group table
- (when JoinFlag is TRUE).
- @retval EFI_NOT_FOUND The group address is not in the group table (when
- JoinFlag is FALSE).
- @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
- **/
- EFI_STATUS
- EFIAPI
- Udp6Groups (
- IN EFI_UDP6_PROTOCOL *This,
- IN BOOLEAN JoinFlag,
- IN EFI_IPv6_ADDRESS *MulticastAddress OPTIONAL
- )
- {
- EFI_STATUS Status;
- UDP6_INSTANCE_DATA *Instance;
- EFI_IP6_PROTOCOL *Ip;
- EFI_TPL OldTpl;
- EFI_IPv6_ADDRESS *McastIp;
- if ((This == NULL) || (JoinFlag && (MulticastAddress == NULL))) {
- return EFI_INVALID_PARAMETER;
- }
- McastIp = NULL;
- if (JoinFlag) {
- if (!IP6_IS_MULTICAST (MulticastAddress)) {
- return EFI_INVALID_PARAMETER;
- }
- McastIp = AllocateCopyPool (sizeof (EFI_IPv6_ADDRESS), MulticastAddress);
- if (McastIp == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- if (!Instance->Configured) {
- if (McastIp != NULL) {
- FreePool (McastIp);
- }
- return EFI_NOT_STARTED;
- }
- Ip = Instance->IpInfo->Ip.Ip6;
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- //
- // Invoke the Ip instance the Udp6 instance consumes to do the group operation.
- //
- Status = Ip->Groups (Ip, JoinFlag, MulticastAddress);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- //
- // Keep a local copy of the configured multicast IPs because IpIo receives
- // datagrams from the 0 station address IP instance and then UDP delivers to
- // the matched instance. This copy of multicast IPs is used to avoid receive
- // the multicast datagrams destinated to multicast IPs the other instances configured.
- //
- if (JoinFlag) {
- Status = NetMapInsertTail (&Instance->McastIps, (VOID *)McastIp, NULL);
- } else {
- Status = NetMapIterate (&Instance->McastIps, Udp6LeaveGroup, MulticastAddress);
- if ((MulticastAddress != NULL) && (Status == EFI_ABORTED)) {
- Status = EFI_SUCCESS;
- }
- }
- ON_EXIT:
- gBS->RestoreTPL (OldTpl);
- if (EFI_ERROR (Status)) {
- if (McastIp != NULL) {
- FreePool (McastIp);
- }
- }
- return Status;
- }
- /**
- This function places a sending request to this instance of the EFI UDPv6 Protocol,
- alongside the transmit data that was filled by the user.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @param[in] Token Pointer to the completion token that will be
- placed into the transmit queue.
- @retval EFI_SUCCESS The data was queued for transmission.
- @retval EFI_NOT_STARTED This EFI UDPv6 Protocol instance has not been
- started.
- @retval EFI_NO_MAPPING The under-layer IPv6 driver was responsible for
- choosing a source address for this instance, but
- no source address was available for use.
- @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
- This is NULL.
- Token is NULL. Token.Event is NULL.
- Token.Packet.TxData is NULL.
- Token.Packet.TxData.FragmentCount is zero.
- Token.Packet.TxData.DataLength is not equal to the
- sum of fragment lengths.
- One or more of the
- Token.Packet.TxData.FragmentTable[].FragmentLength
- fields is zero.
- One or more of the
- Token.Packet.TxData.FragmentTable[].FragmentBuffer
- fields is NULL. One or more of the
- Token.Packet.TxData.UdpSessionData.DestinationAddress
- are not valid unicast IPv6
- addresses if the UdpSessionData is not NULL.
- Token.Packet.TxData.UdpSessionData.
- DestinationAddress is NULL
- Token.Packet.TxData.UdpSessionData.
- DestinationPort
- is zero.
- Token.Packet.TxData.UdpSessionData is NULL and this
- instance's UdpConfigData.RemoteAddress is unspecified.
- @retval EFI_ACCESS_DENIED The transmit completion token with the same
- Token.Event is already in the transmit queue.
- @retval EFI_NOT_READY The completion token could not be queued because
- the transmit queue is full.
- @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data.
- @retval EFI_NOT_FOUND There is no route to the destination network or
- address.
- @retval EFI_BAD_BUFFER_SIZE The data length is greater than the maximum UDP
- packet size. Or, the length of the IP header + UDP
- header + data length is greater than MTU if
- DoNotFragment is TRUE.
- **/
- EFI_STATUS
- EFIAPI
- Udp6Transmit (
- IN EFI_UDP6_PROTOCOL *This,
- IN EFI_UDP6_COMPLETION_TOKEN *Token
- )
- {
- EFI_STATUS Status;
- UDP6_INSTANCE_DATA *Instance;
- EFI_TPL OldTpl;
- NET_BUF *Packet;
- EFI_UDP_HEADER *Udp6Header;
- EFI_UDP6_CONFIG_DATA *ConfigData;
- EFI_IPv6_ADDRESS Source;
- EFI_IPv6_ADDRESS Destination;
- EFI_UDP6_TRANSMIT_DATA *TxData;
- EFI_UDP6_SESSION_DATA *UdpSessionData;
- UDP6_SERVICE_DATA *Udp6Service;
- IP_IO_OVERRIDE Override;
- UINT16 HeadSum;
- EFI_IP_ADDRESS IpDestAddr;
- if ((This == NULL) || (Token == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- if (!Instance->Configured) {
- return EFI_NOT_STARTED;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- //
- // Validate the Token, if the token is invalid return the error code.
- //
- Status = Udp6ValidateTxToken (Instance, Token);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- if (EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp6TokenExist, Token)) ||
- EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp6TokenExist, Token))
- )
- {
- //
- // Try to find a duplicate token in the two token maps, if found, return
- // EFI_ACCESS_DENIED.
- //
- Status = EFI_ACCESS_DENIED;
- goto ON_EXIT;
- }
- TxData = Token->Packet.TxData;
- //
- // Create a net buffer to hold the user buffer and the udp header.
- //
- Packet = NetbufFromExt (
- (NET_FRAGMENT *)TxData->FragmentTable,
- TxData->FragmentCount,
- UDP6_HEADER_SIZE,
- 0,
- Udp6NetVectorExtFree,
- NULL
- );
- if (Packet == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- //
- // Store the IpIo in ProtoData.
- //
- Udp6Service = Instance->Udp6Service;
- *((UINTN *)&Packet->ProtoData[0]) = (UINTN)(Udp6Service->IpIo);
- Udp6Header = (EFI_UDP_HEADER *)NetbufAllocSpace (Packet, UDP6_HEADER_SIZE, TRUE);
- ASSERT (Udp6Header != NULL);
- if (Udp6Header == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- ConfigData = &Instance->ConfigData;
- //
- // Fill the udp header.
- //
- Udp6Header->SrcPort = HTONS (ConfigData->StationPort);
- Udp6Header->DstPort = HTONS (ConfigData->RemotePort);
- Udp6Header->Length = HTONS ((UINT16)Packet->TotalSize);
- Udp6Header->Checksum = 0;
- //
- // Set the UDP Header in NET_BUF, this UDP header is for IP6 can fast get the
- // Udp header for pseudoHeadCheckSum.
- //
- Packet->Udp = Udp6Header;
- UdpSessionData = TxData->UdpSessionData;
- if (UdpSessionData != NULL) {
- //
- // Set the Destination according to the specified
- // UdpSessionData.
- //
- if (UdpSessionData->DestinationPort != 0) {
- Udp6Header->DstPort = HTONS (UdpSessionData->DestinationPort);
- }
- IP6_COPY_ADDRESS (&Source, &ConfigData->StationAddress);
- if (!NetIp6IsUnspecifiedAddr (&UdpSessionData->DestinationAddress)) {
- IP6_COPY_ADDRESS (&Destination, &UdpSessionData->DestinationAddress);
- } else {
- IP6_COPY_ADDRESS (&Destination, &ConfigData->RemoteAddress);
- }
- //
- // Calculate the pseudo head checksum using the overridden parameters.
- //
- if (!NetIp6IsUnspecifiedAddr (&ConfigData->StationAddress)) {
- HeadSum = NetIp6PseudoHeadChecksum (
- &Source,
- &Destination,
- EFI_IP_PROTO_UDP,
- 0
- );
- //
- // calculate the checksum.
- //
- Udp6Header->Checksum = Udp6Checksum (Packet, HeadSum);
- if (Udp6Header->Checksum == 0) {
- //
- // If the calculated checksum is 0, fill the Checksum field with all ones.
- //
- Udp6Header->Checksum = 0xffff;
- }
- } else {
- //
- // Set the checksum is zero if the ConfigData->StationAddress is unspecified
- // and the Ipv6 will fill the correct value of this checksum.
- //
- Udp6Header->Checksum = 0;
- }
- } else {
- //
- // UdpSessionData is NULL, use the address and port information previously configured.
- //
- IP6_COPY_ADDRESS (&Destination, &ConfigData->RemoteAddress);
- HeadSum = Instance->HeadSum;
- //
- // calculate the checksum.
- //
- Udp6Header->Checksum = Udp6Checksum (Packet, HeadSum);
- if (Udp6Header->Checksum == 0) {
- //
- // If the calculated checksum is 0, fill the Checksum field with all ones.
- //
- Udp6Header->Checksum = 0xffff;
- }
- }
- //
- // Fill the IpIo Override data.
- //
- Override.Ip6OverrideData.Protocol = EFI_IP_PROTO_UDP;
- Override.Ip6OverrideData.HopLimit = ConfigData->HopLimit;
- Override.Ip6OverrideData.FlowLabel = 0;
- //
- // Save the token into the TxToken map.
- //
- Status = NetMapInsertTail (&Instance->TxTokens, Token, Packet);
- if (EFI_ERROR (Status)) {
- goto FREE_PACKET;
- }
- //
- // Send out this datagram through IpIo.
- //
- if (UdpSessionData != NULL) {
- IP6_COPY_ADDRESS (&(IpDestAddr.v6), &Destination);
- } else {
- ZeroMem (&IpDestAddr.v6, sizeof (EFI_IPv6_ADDRESS));
- }
- Status = IpIoSend (
- Udp6Service->IpIo,
- Packet,
- Instance->IpInfo,
- Instance,
- Token,
- &IpDestAddr,
- &Override
- );
- if (EFI_ERROR (Status)) {
- //
- // Remove this token from the TxTokens.
- //
- Udp6RemoveToken (&Instance->TxTokens, Token);
- }
- FREE_PACKET:
- NetbufFree (Packet);
- ON_EXIT:
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- This function places a completion token into the receive packet queue. This function
- is always asynchronous.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @param[in] Token Pointer to a token that is associated with the
- receive data descriptor.
- @retval EFI_SUCCESS The receive completion token was cached.
- @retval EFI_NOT_STARTED This EFI UDPv6 Protocol instance has not been
- started.
- @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
- BOOTP, RARP, etc.) is not finished yet.
- @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
- This is NULL. Token is NULL. Token.Event is NULL.
- @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
- due to a lack of system resources (usually
- memory).
- @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
- The EFI UDPv6 Protocol instance has been reset to
- startup defaults.
- @retval EFI_ACCESS_DENIED A receive completion token with the same
- Token.Event is already in the receive queue.
- @retval EFI_NOT_READY The receive request could not be queued because
- the receive queue is full.
- **/
- EFI_STATUS
- EFIAPI
- Udp6Receive (
- IN EFI_UDP6_PROTOCOL *This,
- IN EFI_UDP6_COMPLETION_TOKEN *Token
- )
- {
- EFI_STATUS Status;
- UDP6_INSTANCE_DATA *Instance;
- EFI_TPL OldTpl;
- if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- if (!Instance->Configured) {
- return EFI_NOT_STARTED;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- if (EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp6TokenExist, Token)) ||
- EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp6TokenExist, Token))
- )
- {
- //
- // Return EFI_ACCESS_DENIED if the specified token is already in the TxTokens or
- // RxTokens map.
- //
- Status = EFI_ACCESS_DENIED;
- goto ON_EXIT;
- }
- Token->Packet.RxData = NULL;
- //
- // Save the token into the RxTokens map.
- //
- Status = NetMapInsertTail (&Instance->RxTokens, Token, NULL);
- if (EFI_ERROR (Status)) {
- Status = EFI_NOT_READY;
- goto ON_EXIT;
- }
- //
- // If there is an icmp error, report it.
- //
- Udp6ReportIcmpError (Instance);
- //
- // Try to delivered the received datagrams.
- //
- Udp6InstanceDeliverDgram (Instance);
- //
- // Dispatch the DPC queued by the NotifyFunction of Token->Event.
- //
- DispatchDpc ();
- ON_EXIT:
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- This function is used to abort a pending transmit or receive request.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @param[in] Token Pointer to a token that has been issued by
- EFI_UDP6_PROTOCOL.Transmit() or
- EFI_UDP6_PROTOCOL.Receive(). This parameter is
- optional and may be NULL.
- @retval EFI_SUCCESS The asynchronous I/O request was aborted, and
- Token.Event was signaled. When Token is NULL, all
- pending requests are aborted and their events are
- signaled.
- @retval EFI_INVALID_PARAMETER This is NULL.
- @retval EFI_NOT_STARTED This instance has not been started.
- @retval EFI_NO_MAPPING When using the default address, configuration
- (DHCP, BOOTP, RARP, etc.) is not finished yet.
- @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O
- request is not found in the transmit or receive
- queue. It is either completed or not issued by
- Transmit() or Receive().
- **/
- EFI_STATUS
- EFIAPI
- Udp6Cancel (
- IN EFI_UDP6_PROTOCOL *This,
- IN EFI_UDP6_COMPLETION_TOKEN *Token OPTIONAL
- )
- {
- EFI_STATUS Status;
- UDP6_INSTANCE_DATA *Instance;
- EFI_TPL OldTpl;
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- if (!Instance->Configured) {
- return EFI_NOT_STARTED;
- }
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- //
- // Cancel the tokens specified by Token for this instance.
- //
- Status = Udp6InstanceCancelToken (Instance, Token);
- //
- // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
- //
- DispatchDpc ();
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- This function can be used by network drivers and applications to increase the rate that
- data packets are moved between the communications device and the transmit/receive queues.
- @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance.
- @retval EFI_SUCCESS Incoming or outgoing data was processed.
- @retval EFI_INVALID_PARAMETER This is NULL.
- @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
- @retval EFI_TIMEOUT Data was dropped out of the transmit and/or
- receive queue.
- **/
- EFI_STATUS
- EFIAPI
- Udp6Poll (
- IN EFI_UDP6_PROTOCOL *This
- )
- {
- UDP6_INSTANCE_DATA *Instance;
- EFI_IP6_PROTOCOL *Ip;
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
- Ip = Instance->IpInfo->Ip.Ip6;
- //
- // Invode the Ip instance consumed by the udp instance to do the poll operation.
- //
- return Ip->Poll (Ip);
- }
|