3 Copyright (c) 2005 - 2006, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
22 #include "SockImpl.h"
\r
26 Check whether the Event is in the List.
\r
28 @param List Pointer to the token list to be searched.
\r
29 @param Event The event to be checked.
\r
31 @retval BOOLEAN If TRUE, the specific Event exists in the List. If
\r
32 FALSE, the specific Event is not in the List.
\r
37 SockTokenExistedInList (
\r
38 IN NET_LIST_ENTRY *List,
\r
42 NET_LIST_ENTRY *ListEntry;
\r
43 SOCK_TOKEN *SockToken;
\r
45 NET_LIST_FOR_EACH (ListEntry, List) {
\r
46 SockToken = NET_LIST_USER_STRUCT (
\r
52 if (Event == SockToken->Token->Event) {
\r
62 Call SockTokenExistedInList() to check whether the Event is
\r
63 in the related socket's lists.
\r
65 @param Sock Pointer to the instance's socket.
\r
66 @param Event The event to be checked.
\r
68 @return The specific Event exists in one of socket's lists or not.
\r
78 if (SockTokenExistedInList (&Sock->SndTokenList, Event) ||
\r
79 SockTokenExistedInList (&Sock->ProcessingSndTokenList, Event) ||
\r
80 SockTokenExistedInList (&Sock->RcvTokenList, Event) ||
\r
81 SockTokenExistedInList (&Sock->ListenTokenList, Event)
\r
87 if ((Sock->ConnectionToken != NULL) &&
\r
88 (Sock->ConnectionToken->Event == Event)) {
\r
93 if ((Sock->CloseToken != NULL) && (Sock->CloseToken->Event == Event)) {
\r
102 Buffer a token into the specific list of socket Sock.
\r
104 @param Sock Pointer to the instance's socket.
\r
105 @param List Pointer to the list to store the token.
\r
106 @param Token Pointer to the token to be buffered.
\r
107 @param DataLen The data length of the buffer contained in Token.
\r
109 @return Pointer to the token that wraps Token. If NULL, error condition occurred.
\r
115 IN NET_LIST_ENTRY *List,
\r
120 SOCK_TOKEN *SockToken;
\r
122 SockToken = NetAllocatePool (sizeof (SOCK_TOKEN));
\r
123 if (NULL == SockToken) {
\r
125 SOCK_DEBUG_ERROR (("SockBufferIOToken: No Memory "
\r
126 "to allocate SockToken\n"));
\r
131 SockToken->Sock = Sock;
\r
132 SockToken->Token = (SOCK_COMPLETION_TOKEN *) Token;
\r
133 SockToken->RemainDataLen = DataLen;
\r
134 NetListInsertTail (List, &SockToken->TokenList);
\r
141 Destory the socket Sock and its associated protocol control block.
\r
143 @param Sock The socket to be destroyed.
\r
145 @retval EFI_SUCCESS The socket Sock is destroyed successfully.
\r
146 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
\r
156 ASSERT (Sock && Sock->ProtoHandler);
\r
158 if (Sock->IsDestroyed) {
\r
159 return EFI_SUCCESS;
\r
162 Sock->IsDestroyed = TRUE;
\r
164 Status = NET_TRYLOCK (&(Sock->Lock));
\r
165 if (EFI_ERROR (Status)) {
\r
167 SOCK_DEBUG_ERROR (("SockDestroyChild: Get the lock to "
\r
168 "access socket failed with %r\n", Status));
\r
170 return EFI_ACCESS_DENIED;
\r
174 // force protocol layer to detach the PCB
\r
176 Status = Sock->ProtoHandler (Sock, SOCK_DETACH, NULL);
\r
178 if (EFI_ERROR (Status)) {
\r
180 SOCK_DEBUG_ERROR (("SockDestroyChild: Protocol detach socket"
\r
181 " failed with %r\n", Status));
\r
183 Sock->IsDestroyed = FALSE;
\r
184 } else if (SOCK_IS_CONFIGURED (Sock)) {
\r
186 SockConnFlush (Sock);
\r
187 SockSetState (Sock, SO_CLOSED);
\r
189 Sock->ConfigureState = SO_UNCONFIGURED;
\r
192 NET_UNLOCK (&(Sock->Lock));
\r
194 if (EFI_ERROR (Status)) {
\r
198 SockDestroy (Sock);
\r
199 return EFI_SUCCESS;
\r
204 Create a socket and its associated protocol control block
\r
205 with the intial data SockInitData and protocol specific
\r
208 @param SockInitData Inital data to setting the socket.
\r
209 @param ProtoData Pointer to the protocol specific data.
\r
210 @param Len Length of the protocol specific data.
\r
212 @return Pointer to the newly created socket. If NULL, error condition occured.
\r
217 IN SOCK_INIT_DATA *SockInitData
\r
224 // create a new socket
\r
226 Sock = SockCreate (SockInitData);
\r
227 if (NULL == Sock) {
\r
229 SOCK_DEBUG_ERROR (("SockCreateChild: No resource to "
\r
230 "create a new socket\n"));
\r
235 Status = NET_TRYLOCK (&(Sock->Lock));
\r
236 if (EFI_ERROR (Status)) {
\r
238 SOCK_DEBUG_ERROR (("SockCreateChild: Get the lock to "
\r
239 "access socket failed with %r\n", Status));
\r
241 SockDestroy (Sock);
\r
245 // inform the protocol layer to attach the socket
\r
246 // with a new protocol control block
\r
248 Status = Sock->ProtoHandler (Sock, SOCK_ATTACH, NULL);
\r
249 if (EFI_ERROR (Status)) {
\r
251 SOCK_DEBUG_ERROR (("SockCreateChild: Protocol failed to"
\r
252 " attach a socket with %r\n", Status));
\r
254 SockDestroy (Sock);
\r
258 NET_UNLOCK (&(Sock->Lock));
\r
264 Configure the specific socket Sock using configuration data
\r
267 @param Sock Pointer to the socket to be configured.
\r
268 @param ConfigData Pointer to the configuration data.
\r
270 @retval EFI_SUCCESS The socket is configured successfully.
\r
271 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket or the
\r
272 socket is already configured.
\r
278 IN VOID *ConfigData
\r
283 Status = NET_TRYLOCK (&(Sock->Lock));
\r
284 if (EFI_ERROR (Status)) {
\r
286 SOCK_DEBUG_ERROR (("SockConfigure: Get the access for "
\r
287 "socket failed with %r", Status));
\r
289 return EFI_ACCESS_DENIED;
\r
292 if (SOCK_IS_CONFIGURED (Sock)) {
\r
293 Status = EFI_ACCESS_DENIED;
\r
297 ASSERT (Sock->State == SO_CLOSED);
\r
299 Status = Sock->ProtoHandler (Sock, SOCK_CONFIGURE, ConfigData);
\r
302 NET_UNLOCK (&(Sock->Lock));
\r
309 Initiate a connection establishment process.
\r
311 @param Sock Pointer to the socket to initiate the initate the
\r
313 @param Token Pointer to the token used for the connection
\r
316 @retval EFI_SUCCESS The connection is initialized successfully.
\r
317 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
\r
318 socket is closed, or the socket is not configured to
\r
319 be an active one, or the token is already in one of
\r
320 this socket's lists.
\r
321 @retval EFI_NO_MAPPING The IP address configuration operation is not
\r
323 @retval EFI_NOT_STARTED The socket is not configured.
\r
335 Status = NET_TRYLOCK (&(Sock->Lock));
\r
336 if (EFI_ERROR (Status)) {
\r
338 SOCK_DEBUG_ERROR (("SockConnect: Get the access for "
\r
339 "socket failed with %r", Status));
\r
341 return EFI_ACCESS_DENIED;
\r
344 if (SOCK_IS_NO_MAPPING (Sock)) {
\r
345 Status = EFI_NO_MAPPING;
\r
349 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
351 Status = EFI_NOT_STARTED;
\r
355 if (!SOCK_IS_CLOSED (Sock) || !SOCK_IS_CONFIGURED_ACTIVE (Sock)) {
\r
357 Status = EFI_ACCESS_DENIED;
\r
361 Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
\r
363 if (SockTokenExisted (Sock, Event)) {
\r
365 Status = EFI_ACCESS_DENIED;
\r
369 Sock->ConnectionToken = (SOCK_COMPLETION_TOKEN *) Token;
\r
370 SockSetState (Sock, SO_CONNECTING);
\r
371 Status = Sock->ProtoHandler (Sock, SOCK_CONNECT, NULL);
\r
374 NET_UNLOCK (&(Sock->Lock));
\r
380 Issue a listen token to get an existed connected network instance
\r
381 or wait for a connection if there is none.
\r
383 @param Sock Pointer to the socket to accept connections.
\r
384 @param Token The token to accept a connection.
\r
386 @retval EFI_SUCCESS Either a connection is accpeted or the Token is
\r
387 buffered for further acception.
\r
388 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
\r
389 socket is closed, or the socket is not configured to
\r
390 be a passive one, or the token is already in one of
\r
391 this socket's lists.
\r
392 @retval EFI_NO_MAPPING The IP address configuration operation is not
\r
394 @retval EFI_NOT_STARTED The socket is not configured.
\r
395 @retval EFI_OUT_OF_RESOURCE Failed to buffer the Token due to memory limit.
\r
404 EFI_TCP4_LISTEN_TOKEN *ListenToken;
\r
405 NET_LIST_ENTRY *ListEntry;
\r
410 ASSERT (SOCK_STREAM == Sock->Type);
\r
412 Status = NET_TRYLOCK (&(Sock->Lock));
\r
413 if (EFI_ERROR (Status)) {
\r
415 SOCK_DEBUG_ERROR (("SockAccept: Get the access for socket"
\r
416 " failed with %r", Status));
\r
418 return EFI_ACCESS_DENIED;
\r
421 if (SOCK_IS_NO_MAPPING (Sock)) {
\r
422 Status = EFI_NO_MAPPING;
\r
426 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
428 Status = EFI_NOT_STARTED;
\r
432 if (!SOCK_IS_LISTENING (Sock)) {
\r
434 Status = EFI_ACCESS_DENIED;
\r
438 Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
\r
440 if (SockTokenExisted (Sock, Event)) {
\r
442 Status = EFI_ACCESS_DENIED;
\r
446 ListenToken = (EFI_TCP4_LISTEN_TOKEN *) Token;
\r
449 // Check if a connection has already in this Sock->ConnectionList
\r
451 NET_LIST_FOR_EACH (ListEntry, &Sock->ConnectionList) {
\r
453 Socket = NET_LIST_USER_STRUCT (ListEntry, SOCKET, ConnectionList);
\r
455 if (SOCK_IS_CONNECTED (Socket)) {
\r
456 ListenToken->NewChildHandle = Socket->SockHandle;
\r
457 SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
\r
459 NetListRemoveEntry (ListEntry);
\r
461 ASSERT (Socket->Parent);
\r
463 Socket->Parent->ConnCnt--;
\r
465 SOCK_DEBUG_WARN (("SockAccept: Accept a socket,"
\r
466 "now conncount is %d", Socket->Parent->ConnCnt)
\r
468 Socket->Parent = NULL;
\r
475 // Buffer this token for latter incoming connection request
\r
477 if (NULL == SockBufferToken (Sock, &(Sock->ListenTokenList), Token, 0)) {
\r
479 Status = EFI_OUT_OF_RESOURCES;
\r
483 NET_UNLOCK (&(Sock->Lock));
\r
490 Issue a token with data to the socket to send out.
\r
492 @param Sock Pointer to the socket to process the token with
\r
494 @param Token The token with data that needs to send out.
\r
496 @retval EFI_SUCCESS The token is processed successfully.
\r
497 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
\r
498 socket is closed, or the socket is not in a
\r
499 synchronized state , or the token is already in one
\r
500 of this socket's lists.
\r
501 @retval EFI_NO_MAPPING The IP address configuration operation is not
\r
503 @retval EFI_NOT_STARTED The socket is not configured.
\r
504 @retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
\r
513 SOCK_IO_TOKEN *SndToken;
\r
516 EFI_TCP4_TRANSMIT_DATA *TxData;
\r
518 SOCK_TOKEN *SockToken;
\r
521 ASSERT (SOCK_STREAM == Sock->Type);
\r
523 Status = NET_TRYLOCK (&(Sock->Lock));
\r
524 if (EFI_ERROR (Status)) {
\r
526 SOCK_DEBUG_ERROR (("SockSend: Get the access for socket"
\r
527 " failed with %r", Status));
\r
529 return EFI_ACCESS_DENIED;
\r
532 if (SOCK_IS_NO_MAPPING (Sock)) {
\r
533 Status = EFI_NO_MAPPING;
\r
537 SndToken = (SOCK_IO_TOKEN *) Token;
\r
538 TxData = (EFI_TCP4_TRANSMIT_DATA *) SndToken->Packet.TxData;
\r
540 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
541 Status = EFI_NOT_STARTED;
\r
545 if (!(SOCK_IS_CONNECTING (Sock) || SOCK_IS_CONNECTED (Sock))) {
\r
547 Status = EFI_ACCESS_DENIED;
\r
552 // check if a token is already in the token buffer
\r
554 Event = SndToken->Token.Event;
\r
556 if (SockTokenExisted (Sock, Event)) {
\r
557 Status = EFI_ACCESS_DENIED;
\r
561 DataLen = (UINT32) TxData->DataLength;
\r
564 // process this sending token now or buffer it only?
\r
566 FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
\r
568 if ((FreeSpace < Sock->SndBuffer.LowWater) || !SOCK_IS_CONNECTED (Sock)) {
\r
570 SockToken = SockBufferToken (
\r
572 &Sock->SndTokenList,
\r
577 if (NULL == SockToken) {
\r
578 Status = EFI_OUT_OF_RESOURCES;
\r
582 SockToken = SockBufferToken (
\r
584 &Sock->ProcessingSndTokenList,
\r
589 if (NULL == SockToken) {
\r
590 SOCK_DEBUG_ERROR (("SockSend: Failed to buffer IO token into"
\r
591 " socket processing SndToken List\n", Status));
\r
593 Status = EFI_OUT_OF_RESOURCES;
\r
597 Status = SockProcessTcpSndData (Sock, TxData);
\r
599 if (EFI_ERROR (Status)) {
\r
600 SOCK_DEBUG_ERROR (("SockSend: Failed to process "
\r
601 "Snd Data\n", Status));
\r
603 NetListRemoveEntry (&(SockToken->TokenList));
\r
604 NetFreePool (SockToken);
\r
609 NET_UNLOCK (&(Sock->Lock));
\r
615 Issue a token to get data from the socket.
\r
617 @param Sock Pointer to the socket to get data from.
\r
618 @param Token The token to store the received data from the
\r
621 @retval EFI_SUCCESS The token is processed successfully.
\r
622 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
\r
623 socket is closed, or the socket is not in a
\r
624 synchronized state , or the token is already in one
\r
625 of this socket's lists.
\r
626 @retval EFI_NO_MAPPING The IP address configuration operation is not
\r
628 @retval EFI_NOT_STARTED The socket is not configured.
\r
629 @retval EFI_CONNECTION_FIN The connection is closed and there is no more data.
\r
630 @retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
\r
639 SOCK_IO_TOKEN *RcvToken;
\r
644 ASSERT (SOCK_STREAM == Sock->Type);
\r
646 Status = NET_TRYLOCK (&(Sock->Lock));
\r
647 if (EFI_ERROR (Status)) {
\r
649 SOCK_DEBUG_ERROR (("SockRcv: Get the access for socket"
\r
650 " failed with %r", Status));
\r
652 return EFI_ACCESS_DENIED;
\r
655 if (SOCK_IS_NO_MAPPING (Sock)) {
\r
657 Status = EFI_NO_MAPPING;
\r
661 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
663 Status = EFI_NOT_STARTED;
\r
667 if (!(SOCK_IS_CONNECTED (Sock) || SOCK_IS_CONNECTING (Sock))) {
\r
669 Status = EFI_ACCESS_DENIED;
\r
673 RcvToken = (SOCK_IO_TOKEN *) Token;
\r
676 // check if a token is already in the token buffer of this socket
\r
678 Event = RcvToken->Token.Event;
\r
679 if (SockTokenExisted (Sock, Event)) {
\r
680 Status = EFI_ACCESS_DENIED;
\r
684 RcvToken = (SOCK_IO_TOKEN *) Token;
\r
685 RcvdBytes = GET_RCV_DATASIZE (Sock);
\r
688 // check whether an error has happened before
\r
690 if (EFI_ABORTED != Sock->SockError) {
\r
692 SIGNAL_TOKEN (&(RcvToken->Token), Sock->SockError);
\r
693 Sock->SockError = EFI_ABORTED;
\r
698 // check whether can not receive and there is no any
\r
699 // data buffered in Sock->RcvBuffer
\r
701 if (SOCK_IS_NO_MORE_DATA (Sock) && (0 == RcvdBytes)) {
\r
703 Status = EFI_CONNECTION_FIN;
\r
707 if (RcvdBytes != 0) {
\r
708 Status = SockProcessRcvToken (Sock, RcvToken);
\r
710 if (EFI_ERROR (Status)) {
\r
714 Status = Sock->ProtoHandler (Sock, SOCK_CONSUMED, NULL);
\r
717 if (NULL == SockBufferToken (Sock, &Sock->RcvTokenList, RcvToken, 0)) {
\r
718 Status = EFI_OUT_OF_RESOURCES;
\r
723 NET_UNLOCK (&(Sock->Lock));
\r
729 Reset the socket and its associated protocol control block.
\r
731 @param Sock Pointer to the socket to be flushed.
\r
733 @retval EFI_SUCCESS The socket is flushed successfully.
\r
734 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
\r
744 ASSERT (SOCK_STREAM == Sock->Type);
\r
746 Status = NET_TRYLOCK (&(Sock->Lock));
\r
747 if (EFI_ERROR (Status)) {
\r
749 SOCK_DEBUG_ERROR (("SockFlush: Get the access for socket"
\r
750 " failed with %r", Status));
\r
752 return EFI_ACCESS_DENIED;
\r
755 if (!SOCK_IS_CONFIGURED (Sock)) {
\r
759 Status = Sock->ProtoHandler (Sock, SOCK_FLUSH, NULL);
\r
760 if (EFI_ERROR (Status)) {
\r
762 SOCK_DEBUG_ERROR (("SockFlush: Protocol failed handling"
\r
763 " SOCK_FLUSH with %r", Status));
\r
768 SOCK_ERROR (Sock, EFI_ABORTED);
\r
769 SockConnFlush (Sock);
\r
770 SockSetState (Sock, SO_CLOSED);
\r
772 Sock->ConfigureState = SO_UNCONFIGURED;
\r
775 NET_UNLOCK (&(Sock->Lock));
\r
781 Close or abort the socket associated connection.
\r
783 @param Sock Pointer to the socket of the connection to close or
\r
785 @param Token The token for close operation.
\r
786 @param OnAbort TRUE for aborting the connection, FALSE to close it.
\r
788 @retval EFI_SUCCESS The close or abort operation is initialized
\r
790 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
\r
791 socket is closed, or the socket is not in a
\r
792 synchronized state , or the token is already in one
\r
793 of this socket's lists.
\r
794 @retval EFI_NO_MAPPING The IP address configuration operation is not
\r
796 @retval EFI_NOT_STARTED The socket is not configured.
\r
809 ASSERT (SOCK_STREAM == Sock->Type);
\r
811 Status = NET_TRYLOCK (&(Sock->Lock));
\r
812 if (EFI_ERROR (Status)) {
\r
813 SOCK_DEBUG_ERROR (("SockClose: Get the access for socket"
\r
814 " failed with %r", Status));
\r
816 return EFI_ACCESS_DENIED;
\r
819 if (SOCK_IS_NO_MAPPING (Sock)) {
\r
820 Status = EFI_NO_MAPPING;
\r
824 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
825 Status = EFI_NOT_STARTED;
\r
829 if (SOCK_IS_DISCONNECTING (Sock)) {
\r
830 Status = EFI_ACCESS_DENIED;
\r
834 Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
\r
836 if (SockTokenExisted (Sock, Event)) {
\r
837 Status = EFI_ACCESS_DENIED;
\r
841 Sock->CloseToken = Token;
\r
842 SockSetState (Sock, SO_DISCONNECTING);
\r
845 Status = Sock->ProtoHandler (Sock, SOCK_ABORT, NULL);
\r
847 Status = Sock->ProtoHandler (Sock, SOCK_CLOSE, NULL);
\r
851 NET_UNLOCK (&(Sock->Lock));
\r
857 Get the mode data of the low layer protocol.
\r
859 @param Sock Pointer to the socket to get mode data from.
\r
860 @param Mode Pointer to the data to store the low layer mode
\r
863 @retval EFI_SUCCESS The mode data is got successfully.
\r
864 @retval EFI_NOT_STARTED The socket is not configured.
\r
873 return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);
\r
878 Configure the low level protocol to join a multicast group for
\r
879 this socket's connection.
\r
881 @param Sock Pointer to the socket of the connection to join the
\r
882 specific multicast group.
\r
883 @param GroupInfo Pointer to the multicast group info.
\r
885 @retval EFI_SUCCESS The configuration is done successfully.
\r
886 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
\r
887 @retval EFI_NOT_STARTED The socket is not configured.
\r
898 Status = NET_TRYLOCK (&(Sock->Lock));
\r
900 if (EFI_ERROR (Status)) {
\r
902 SOCK_DEBUG_ERROR (("SockGroup: Get the access for socket"
\r
903 " failed with %r", Status));
\r
905 return EFI_ACCESS_DENIED;
\r
908 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
909 Status = EFI_NOT_STARTED;
\r
913 Status = Sock->ProtoHandler (Sock, SOCK_GROUP, GroupInfo);
\r
916 NET_UNLOCK (&(Sock->Lock));
\r
922 Add or remove route information in IP route table associated
\r
925 @param Sock Pointer to the socket associated with the IP route
\r
926 table to operate on.
\r
927 @param RouteInfo Pointer to the route information to be processed.
\r
929 @retval EFI_SUCCESS The route table is updated successfully.
\r
930 @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
\r
931 @retval EFI_NO_MAPPING The IP address configuration operation is not
\r
933 @retval EFI_NOT_STARTED The socket is not configured.
\r
944 Status = NET_TRYLOCK (&(Sock->Lock));
\r
945 if (EFI_ERROR (Status)) {
\r
946 SOCK_DEBUG_ERROR (("SockRoute: Get the access for socket"
\r
947 " failed with %r", Status));
\r
949 return EFI_ACCESS_DENIED;
\r
952 if (SOCK_IS_NO_MAPPING (Sock)) {
\r
953 Status = EFI_NO_MAPPING;
\r
957 if (SOCK_IS_UNCONFIGURED (Sock)) {
\r
958 Status = EFI_NOT_STARTED;
\r
962 Status = Sock->ProtoHandler (Sock, SOCK_ROUTE, RouteInfo);
\r
965 NET_UNLOCK (&(Sock->Lock));
\r