]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/TcpDxe/TcpIo.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / TcpDxe / TcpIo.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 Implementation of I/O interfaces between TCP and IpIoLib.\r
3\r
9119637c 4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
a3bcde70 5\r
ecf98fbc 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a3bcde70
HT
7\r
8**/\r
9\r
10#include "TcpMain.h"\r
11\r
12/**\r
13 Packet receive callback function provided to IP_IO, used to call\r
14 the proper function to handle the packet received by IP.\r
15\r
16 @param[in] Status Result of the receive request.\r
17 @param[in] IcmpErr Valid when Status is EFI_ICMP_ERROR.\r
18 @param[in] NetSession The IP session for the received packet.\r
19 @param[in] Pkt Packet received.\r
20 @param[in] Context The data provided by the user for the received packet when\r
21 the callback is registered in IP_IO_OPEN_DATA::RcvdContext.\r
22 This is an optional parameter that may be NULL.\r
23\r
24**/\r
25VOID\r
26EFIAPI\r
27TcpRxCallback (\r
d1050b9d
MK
28 IN EFI_STATUS Status,\r
29 IN UINT8 IcmpErr,\r
30 IN EFI_NET_SESSION_DATA *NetSession,\r
31 IN NET_BUF *Pkt,\r
32 IN VOID *Context OPTIONAL\r
a3bcde70
HT
33 )\r
34{\r
35 if (EFI_SUCCESS == Status) {\r
36 TcpInput (Pkt, &NetSession->Source, &NetSession->Dest, NetSession->IpVersion);\r
37 } else {\r
38 TcpIcmpInput (\r
39 Pkt,\r
40 IcmpErr,\r
41 &NetSession->Source,\r
42 &NetSession->Dest,\r
43 NetSession->IpVersion\r
44 );\r
45 }\r
46}\r
47\r
48/**\r
49 Send the segment to IP via IpIo function.\r
50\r
51 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r
52 @param[in] Nbuf Pointer to the TCP segment to be sent.\r
53 @param[in] Src Source address of the TCP segment.\r
54 @param[in] Dest Destination address of the TCP segment.\r
55 @param[in] Version IP_VERSION_4 or IP_VERSION_6\r
56\r
57 @retval 0 The segment was sent out successfully.\r
58 @retval -1 The segment failed to send.\r
59\r
60**/\r
61INTN\r
62TcpSendIpPacket (\r
63 IN TCP_CB *Tcb,\r
64 IN NET_BUF *Nbuf,\r
65 IN EFI_IP_ADDRESS *Src,\r
66 IN EFI_IP_ADDRESS *Dest,\r
67 IN UINT8 Version\r
68 )\r
69{\r
d1050b9d
MK
70 EFI_STATUS Status;\r
71 IP_IO *IpIo;\r
72 IP_IO_OVERRIDE Override;\r
73 SOCKET *Sock;\r
74 VOID *IpSender;\r
a3bcde70
HT
75 TCP_PROTO_DATA *TcpProto;\r
76\r
77 if (NULL == Tcb) {\r
a3bcde70
HT
78 IpIo = NULL;\r
79 IpSender = IpIoFindSender (&IpIo, Version, Src);\r
80\r
81 if (IpSender == NULL) {\r
c49ca4a2 82 DEBUG ((DEBUG_WARN, "TcpSendIpPacket: No appropriate IpSender.\n"));\r
a3bcde70
HT
83 return -1;\r
84 }\r
85\r
86 if (Version == IP_VERSION_6) {\r
87 //\r
88 // It's tricky here. EFI IPv6 Spec don't allow an instance overriding the\r
89 // destination address if the dest is already specified through the\r
90 // configuration data. Here we get the IpIo we need and use the default IP\r
91 // instance in this IpIo to send the packet. The dest address is configured\r
92 // to be the unspecified address for the default IP instance.\r
93 //\r
94 IpSender = NULL;\r
95 }\r
96 } else {\r
a3bcde70 97 Sock = Tcb->Sk;\r
d1050b9d 98 TcpProto = (TCP_PROTO_DATA *)Sock->ProtoReserved;\r
a3bcde70
HT
99 IpIo = TcpProto->TcpService->IpIo;\r
100 IpSender = Tcb->IpInfo;\r
101\r
102 if (Version == IP_VERSION_6) {\r
103 //\r
104 // It's IPv6 and this TCP segment belongs to a solid TCB, in such case\r
105 // the destination address can't be overridden, so reset the Dest to NULL.\r
106 //\r
9119637c 107 if (!Tcb->RemoteIpZero) {\r
108 Dest = NULL;\r
109 }\r
a3bcde70
HT
110 }\r
111 }\r
112\r
113 ASSERT (Version == IpIo->IpVersion);\r
114\r
115 if (Version == IP_VERSION_4) {\r
116 Override.Ip4OverrideData.TypeOfService = 0;\r
117 Override.Ip4OverrideData.TimeToLive = 255;\r
118 Override.Ip4OverrideData.DoNotFragment = FALSE;\r
119 Override.Ip4OverrideData.Protocol = EFI_IP_PROTO_TCP;\r
120 ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
121 CopyMem (&Override.Ip4OverrideData.SourceAddress, Src, sizeof (EFI_IPv4_ADDRESS));\r
122 } else {\r
123 Override.Ip6OverrideData.Protocol = EFI_IP_PROTO_TCP;\r
124 Override.Ip6OverrideData.HopLimit = 255;\r
125 Override.Ip6OverrideData.FlowLabel = 0;\r
126 }\r
127\r
128 Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, Dest, &Override);\r
129\r
130 if (EFI_ERROR (Status)) {\r
c49ca4a2 131 DEBUG ((DEBUG_ERROR, "TcpSendIpPacket: return %r error\n", Status));\r
a3bcde70
HT
132 return -1;\r
133 }\r
134\r
135 return 0;\r
136}\r
137\r
138/**\r
139 Refresh the remote peer's Neighbor Cache State if already exists.\r
140\r
141 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r
142 @param[in] Neighbor Source address of the TCP segment.\r
143 @param[in] Timeout Time in 100-ns units that this entry will remain\r
144 in the neighbor cache. A value of zero means that\r
145 the entry is permanent. A value of non-zero means\r
146 that the entry is dynamic and will be deleted\r
147 after Timeout.\r
148\r
149 @retval EFI_SUCCESS Successfully updated the neighbor relationship.\r
150 @retval EFI_NOT_STARTED The IpIo is not configured.\r
151 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
152 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.\r
153 @retval EFI_NOT_FOUND This entry is not in the neighbor table.\r
154\r
155**/\r
156EFI_STATUS\r
157Tcp6RefreshNeighbor (\r
158 IN TCP_CB *Tcb,\r
159 IN EFI_IP_ADDRESS *Neighbor,\r
160 IN UINT32 Timeout\r
161 )\r
162{\r
d1050b9d
MK
163 IP_IO *IpIo;\r
164 SOCKET *Sock;\r
a3bcde70
HT
165 TCP_PROTO_DATA *TcpProto;\r
166\r
167 if (NULL == Tcb) {\r
168 IpIo = NULL;\r
169 IpIoFindSender (&IpIo, IP_VERSION_6, Neighbor);\r
170\r
171 if (IpIo == NULL) {\r
c49ca4a2 172 DEBUG ((DEBUG_WARN, "Tcp6AddNeighbor: No appropriate IpIo.\n"));\r
a3bcde70
HT
173 return EFI_NOT_STARTED;\r
174 }\r
a3bcde70
HT
175 } else {\r
176 Sock = Tcb->Sk;\r
d1050b9d 177 TcpProto = (TCP_PROTO_DATA *)Sock->ProtoReserved;\r
a3bcde70
HT
178 IpIo = TcpProto->TcpService->IpIo;\r
179 }\r
180\r
181 return IpIoRefreshNeighbor (IpIo, Neighbor, Timeout);\r
182}\r