1 | /** @file
|
---|
2 |
|
---|
3 | The implementation of EFI Redfish Discover Protocol.
|
---|
4 |
|
---|
5 | (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
---|
6 | Copyright (c) 2022, AMD Incorporated. All rights reserved.
|
---|
7 | Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
---|
8 | Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
|
---|
9 |
|
---|
10 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
11 |
|
---|
12 | **/
|
---|
13 |
|
---|
14 | #include "RedfishDiscoverInternal.h"
|
---|
15 |
|
---|
16 | LIST_ENTRY mRedfishDiscoverList;
|
---|
17 | LIST_ENTRY mRedfishInstanceList;
|
---|
18 | EFI_SMBIOS_PROTOCOL *mSmbios = NULL;
|
---|
19 |
|
---|
20 | UINTN mNumNetworkInterface = 0;
|
---|
21 | UINTN mNumRestExInstance = 0;
|
---|
22 | LIST_ENTRY mEfiRedfishDiscoverNetworkInterface;
|
---|
23 | LIST_ENTRY mEfiRedfishDiscoverRestExInstance;
|
---|
24 |
|
---|
25 | EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID;
|
---|
26 | EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;
|
---|
27 | EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;
|
---|
28 |
|
---|
29 | EFI_STATUS
|
---|
30 | EFIAPI
|
---|
31 | Tcp4GetSubnetInfo (
|
---|
32 | IN EFI_HANDLE ImageHandle,
|
---|
33 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
|
---|
34 | );
|
---|
35 |
|
---|
36 | EFI_STATUS
|
---|
37 | EFIAPI
|
---|
38 | Tcp6GetSubnetInfo (
|
---|
39 | IN EFI_HANDLE ImageHandle,
|
---|
40 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
|
---|
41 | );
|
---|
42 |
|
---|
43 | static REDFISH_DISCOVER_REQUIRED_PROTOCOL gRequiredProtocol[] = {
|
---|
44 | {
|
---|
45 | ProtocolTypeTcp4,
|
---|
46 | L"TCP4 Service Binding Protocol",
|
---|
47 | &gEfiTcp4ProtocolGuid,
|
---|
48 | &gEfiTcp4ServiceBindingProtocolGuid,
|
---|
49 | &mRedfishDiscoverTcp4InstanceGuid,
|
---|
50 | Tcp4GetSubnetInfo
|
---|
51 | },
|
---|
52 | {
|
---|
53 | ProtocolTypeTcp6,
|
---|
54 | L"TCP6 Service Binding Protocol",
|
---|
55 | &gEfiTcp6ProtocolGuid,
|
---|
56 | &gEfiTcp6ServiceBindingProtocolGuid,
|
---|
57 | &mRedfishDiscoverTcp6InstanceGuid,
|
---|
58 | Tcp6GetSubnetInfo
|
---|
59 | },
|
---|
60 | {
|
---|
61 | ProtocolTypeRestEx,
|
---|
62 | L"REST EX Service Binding Protocol",
|
---|
63 | &gEfiRestExProtocolGuid,
|
---|
64 | &gEfiRestExServiceBindingProtocolGuid,
|
---|
65 | &mRedfishDiscoverRestExInstanceGuid,
|
---|
66 | NULL
|
---|
67 | }
|
---|
68 | };
|
---|
69 |
|
---|
70 | /**
|
---|
71 | This function creates REST EX instance for the found Resfish service.
|
---|
72 | by known owner handle.
|
---|
73 |
|
---|
74 | @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
|
---|
75 | @param[in] Token Client token.
|
---|
76 |
|
---|
77 | @retval NULL Instance not found.
|
---|
78 | @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.
|
---|
79 |
|
---|
80 | **/
|
---|
81 | EFI_STATUS
|
---|
82 | CreateRestExInstance (
|
---|
83 | IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance,
|
---|
84 | IN EFI_REDFISH_DISCOVERED_TOKEN *Token
|
---|
85 | )
|
---|
86 | {
|
---|
87 | EFI_STATUS Status;
|
---|
88 |
|
---|
89 | Status = RestExLibCreateChild (
|
---|
90 | Instance->NetworkInterface->OpenDriverControllerHandle,
|
---|
91 | Instance->Owner,
|
---|
92 | FixedPcdGetBool (PcdRedfishDiscoverAccessModeInBand) ? EfiRestExServiceInBandAccess : EfiRestExServiceOutOfBandAccess,
|
---|
93 | EfiRestExConfigHttp,
|
---|
94 | EfiRestExServiceRedfish,
|
---|
95 | &Token->DiscoverList.RedfishInstances->Information.RedfishRestExHandle
|
---|
96 | );
|
---|
97 | return Status;
|
---|
98 | }
|
---|
99 |
|
---|
100 | /**
|
---|
101 | This function gets EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
|
---|
102 | by known owner handle.
|
---|
103 |
|
---|
104 | @param[in] ImageHandle Image handle owns EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
|
---|
105 | @param[in] TargetNetworkInterface Target network interface used by this EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
|
---|
106 | @param[in] DiscoverFlags EFI_REDFISH_DISCOVER_FLAG
|
---|
107 |
|
---|
108 | @retval NULL Instance not found.
|
---|
109 | @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.
|
---|
110 |
|
---|
111 | **/
|
---|
112 | EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *
|
---|
113 | GetInstanceByOwner (
|
---|
114 | IN EFI_HANDLE ImageHandle,
|
---|
115 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterface,
|
---|
116 | IN EFI_REDFISH_DISCOVER_FLAG DiscoverFlags
|
---|
117 | )
|
---|
118 | {
|
---|
119 | EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *ThisInstance;
|
---|
120 |
|
---|
121 | if (IsListEmpty (&mRedfishDiscoverList)) {
|
---|
122 | return NULL;
|
---|
123 | }
|
---|
124 |
|
---|
125 | ThisInstance =
|
---|
126 | (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetFirstNode (&mRedfishDiscoverList);
|
---|
127 | while (TRUE) {
|
---|
128 | if ((ThisInstance->Owner == ImageHandle) &&
|
---|
129 | (ThisInstance->DiscoverFlags == DiscoverFlags) &&
|
---|
130 | (ThisInstance->NetworkInterface == TargetNetworkInterface))
|
---|
131 | {
|
---|
132 | return ThisInstance;
|
---|
133 | }
|
---|
134 |
|
---|
135 | if (IsNodeAtEnd (&mRedfishDiscoverList, &ThisInstance->Entry)) {
|
---|
136 | break;
|
---|
137 | }
|
---|
138 |
|
---|
139 | ThisInstance =
|
---|
140 | (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetNextNode (&mRedfishDiscoverList, &ThisInstance->Entry);
|
---|
141 | }
|
---|
142 |
|
---|
143 | return NULL;
|
---|
144 | }
|
---|
145 |
|
---|
146 | /**
|
---|
147 | This function gets the subnet information of this TCP4 instance.
|
---|
148 |
|
---|
149 | @param[in] ImageHandle EFI handle with this image.
|
---|
150 | @param[in] Instance Instance of Network interface.
|
---|
151 | @retval EFI_STATUS Get subnet information successfully.
|
---|
152 | @retval Otherwise Fail to get subnet information.
|
---|
153 | **/
|
---|
154 | EFI_STATUS
|
---|
155 | EFIAPI
|
---|
156 | Tcp4GetSubnetInfo (
|
---|
157 | IN EFI_HANDLE ImageHandle,
|
---|
158 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
|
---|
159 | )
|
---|
160 | {
|
---|
161 | EFI_STATUS Status;
|
---|
162 | EFI_TCP4_PROTOCOL *Tcp4;
|
---|
163 | EFI_TCP4_CONFIG_DATA Tcp4CfgData;
|
---|
164 | EFI_TCP4_OPTION Tcp4Option;
|
---|
165 | EFI_IP4_MODE_DATA IpModedata;
|
---|
166 | UINT8 SubnetMaskIndex;
|
---|
167 | UINT8 BitMask;
|
---|
168 | UINT8 PrefixLength;
|
---|
169 | BOOLEAN GotPrefixLength;
|
---|
170 |
|
---|
171 | if (Instance == NULL) {
|
---|
172 | return EFI_INVALID_PARAMETER;
|
---|
173 | }
|
---|
174 |
|
---|
175 | Tcp4 = (EFI_TCP4_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
|
---|
176 |
|
---|
177 | ZeroMem ((VOID *)&Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));
|
---|
178 | ZeroMem ((VOID *)&Tcp4Option, sizeof (EFI_TCP4_OPTION));
|
---|
179 | // Give a local host IP address just for getting subnet information.
|
---|
180 | Tcp4CfgData.AccessPoint.UseDefaultAddress = TRUE;
|
---|
181 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[0] = 127;
|
---|
182 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[1] = 0;
|
---|
183 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[2] = 0;
|
---|
184 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[3] = 1;
|
---|
185 | Tcp4CfgData.AccessPoint.RemotePort = 80;
|
---|
186 | Tcp4CfgData.AccessPoint.ActiveFlag = TRUE;
|
---|
187 |
|
---|
188 | Tcp4CfgData.ControlOption = &Tcp4Option;
|
---|
189 | Tcp4Option.ReceiveBufferSize = 65535;
|
---|
190 | Tcp4Option.SendBufferSize = 65535;
|
---|
191 | Tcp4Option.MaxSynBackLog = 5;
|
---|
192 | Tcp4Option.ConnectionTimeout = 60;
|
---|
193 | Tcp4Option.DataRetries = 12;
|
---|
194 | Tcp4Option.FinTimeout = 2;
|
---|
195 | Tcp4Option.KeepAliveProbes = 6;
|
---|
196 | Tcp4Option.KeepAliveTime = 7200;
|
---|
197 | Tcp4Option.KeepAliveInterval = 30;
|
---|
198 | Tcp4Option.EnableNagle = TRUE;
|
---|
199 | Status = Tcp4->Configure (Tcp4, &Tcp4CfgData);
|
---|
200 | if (EFI_ERROR (Status)) {
|
---|
201 | DEBUG ((DEBUG_ERROR, "%a: Can't get subnet information\n", __func__));
|
---|
202 | return Status;
|
---|
203 | }
|
---|
204 |
|
---|
205 | Status = Tcp4->GetModeData (Tcp4, NULL, NULL, &IpModedata, NULL, NULL);
|
---|
206 | if (EFI_ERROR (Status)) {
|
---|
207 | DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __func__));
|
---|
208 | return Status;
|
---|
209 | }
|
---|
210 |
|
---|
211 | IP4_COPY_ADDRESS (&Instance->SubnetMask, &IpModedata.ConfigData.SubnetMask);
|
---|
212 | Instance->SubnetAddr.v4.Addr[0] = IpModedata.ConfigData.StationAddress.Addr[0] & Instance->SubnetMask.v4.Addr[0];
|
---|
213 | Instance->SubnetAddr.v4.Addr[1] = IpModedata.ConfigData.StationAddress.Addr[1] & Instance->SubnetMask.v4.Addr[1];
|
---|
214 | Instance->SubnetAddr.v4.Addr[2] = IpModedata.ConfigData.StationAddress.Addr[2] & Instance->SubnetMask.v4.Addr[2];
|
---|
215 | Instance->SubnetAddr.v4.Addr[3] = IpModedata.ConfigData.StationAddress.Addr[3] & Instance->SubnetMask.v4.Addr[3];
|
---|
216 | //
|
---|
217 | // Calculate the subnet mask prefix.
|
---|
218 | //
|
---|
219 | GotPrefixLength = FALSE;
|
---|
220 | PrefixLength = 0;
|
---|
221 | SubnetMaskIndex = 0;
|
---|
222 | while (GotPrefixLength == FALSE && SubnetMaskIndex < 4) {
|
---|
223 | BitMask = 0x80;
|
---|
224 | while (BitMask != 0) {
|
---|
225 | if ((Instance->SubnetMask.v4.Addr[SubnetMaskIndex] & BitMask) != 0) {
|
---|
226 | PrefixLength++;
|
---|
227 | } else {
|
---|
228 | GotPrefixLength = TRUE;
|
---|
229 | break;
|
---|
230 | }
|
---|
231 |
|
---|
232 | BitMask = BitMask >> 1;
|
---|
233 | }
|
---|
234 |
|
---|
235 | SubnetMaskIndex++;
|
---|
236 | }
|
---|
237 |
|
---|
238 | Instance->SubnetPrefixLength = PrefixLength;
|
---|
239 | return EFI_SUCCESS;
|
---|
240 | }
|
---|
241 |
|
---|
242 | /**
|
---|
243 | This function gets the subnet information of this TCP6 instance.
|
---|
244 |
|
---|
245 | @param[in] ImageHandle EFI handle with this image.
|
---|
246 | @param[in] Instance Instance of Network interface.
|
---|
247 | @retval EFI_STATUS Get subnet information successfully.
|
---|
248 | @retval Otherwise Fail to get subnet information.
|
---|
249 | **/
|
---|
250 | EFI_STATUS
|
---|
251 | EFIAPI
|
---|
252 | Tcp6GetSubnetInfo (
|
---|
253 | IN EFI_HANDLE ImageHandle,
|
---|
254 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
|
---|
255 | )
|
---|
256 | {
|
---|
257 | EFI_STATUS Status;
|
---|
258 | EFI_TCP6_PROTOCOL *Tcp6;
|
---|
259 | EFI_IP6_MODE_DATA IpModedata;
|
---|
260 |
|
---|
261 | if (Instance == NULL) {
|
---|
262 | return EFI_INVALID_PARAMETER;
|
---|
263 | }
|
---|
264 |
|
---|
265 | Tcp6 = (EFI_TCP6_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
|
---|
266 |
|
---|
267 | ZeroMem ((VOID *)&IpModedata, sizeof (EFI_IP6_MODE_DATA));
|
---|
268 | Status = Tcp6->GetModeData (Tcp6, NULL, NULL, &IpModedata, NULL, NULL);
|
---|
269 | if (EFI_ERROR (Status)) {
|
---|
270 | DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __func__));
|
---|
271 | return Status;
|
---|
272 | }
|
---|
273 |
|
---|
274 | if (IpModedata.AddressCount == 0) {
|
---|
275 | DEBUG ((DEBUG_MANAGEABILITY, "%a: No IPv6 address configured.\n", __func__));
|
---|
276 | Instance->SubnetAddrInfoIPv6Number = 0;
|
---|
277 | return EFI_SUCCESS;
|
---|
278 | }
|
---|
279 |
|
---|
280 | if (Instance->SubnetAddrInfoIPv6 != NULL) {
|
---|
281 | FreePool (Instance->SubnetAddrInfoIPv6);
|
---|
282 | Instance->SubnetAddrInfoIPv6 = NULL;
|
---|
283 | }
|
---|
284 |
|
---|
285 | Instance->SubnetAddrInfoIPv6 = AllocateZeroPool (IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO));
|
---|
286 | if (Instance->SubnetAddrInfoIPv6 == NULL) {
|
---|
287 | DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory for IPv6 subnet address information\n", __func__));
|
---|
288 | return EFI_OUT_OF_RESOURCES;
|
---|
289 | }
|
---|
290 |
|
---|
291 | Instance->SubnetAddrInfoIPv6Number = IpModedata.AddressCount;
|
---|
292 | if ((IpModedata.AddressCount != 0) && (IpModedata.AddressList != NULL)) {
|
---|
293 | CopyMem (
|
---|
294 | (VOID *)Instance->SubnetAddrInfoIPv6,
|
---|
295 | (VOID *)&IpModedata.AddressList,
|
---|
296 | IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO)
|
---|
297 | );
|
---|
298 | FreePool (IpModedata.AddressList);
|
---|
299 | }
|
---|
300 |
|
---|
301 | return EFI_SUCCESS;
|
---|
302 | }
|
---|
303 |
|
---|
304 | /**
|
---|
305 | This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
|
---|
306 | instance with the given EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
|
---|
307 |
|
---|
308 | @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
|
---|
309 | NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.
|
---|
310 |
|
---|
311 | @retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.
|
---|
312 | @retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.
|
---|
313 | **/
|
---|
314 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
|
---|
315 | GetTargetNetworkInterfaceInternal (
|
---|
316 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface
|
---|
317 | )
|
---|
318 | {
|
---|
319 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
320 |
|
---|
321 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
322 | while (TRUE) {
|
---|
323 | if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {
|
---|
324 | return ThisNetworkInterface;
|
---|
325 | }
|
---|
326 |
|
---|
327 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
|
---|
328 | return NULL;
|
---|
329 | }
|
---|
330 |
|
---|
331 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
|
---|
332 | }
|
---|
333 |
|
---|
334 | return NULL;
|
---|
335 | }
|
---|
336 |
|
---|
337 | /**
|
---|
338 | This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
|
---|
339 | instance with the given Controller handle.
|
---|
340 |
|
---|
341 | @param[in] ControllerHandle The controller handle associated with network interface.
|
---|
342 |
|
---|
343 | @retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.
|
---|
344 | @retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.
|
---|
345 | **/
|
---|
346 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
|
---|
347 | GetTargetNetworkInterfaceInternalByController (
|
---|
348 | IN EFI_HANDLE ControllerHandle
|
---|
349 | )
|
---|
350 | {
|
---|
351 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
352 |
|
---|
353 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
354 | while (TRUE) {
|
---|
355 | if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {
|
---|
356 | return ThisNetworkInterface;
|
---|
357 | }
|
---|
358 |
|
---|
359 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
|
---|
360 | return NULL;
|
---|
361 | }
|
---|
362 |
|
---|
363 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
|
---|
364 | }
|
---|
365 |
|
---|
366 | return NULL;
|
---|
367 | }
|
---|
368 |
|
---|
369 | /**
|
---|
370 | This function validate if target network interface is ready for discovering
|
---|
371 | Redfish service.
|
---|
372 |
|
---|
373 | @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
|
---|
374 | NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.
|
---|
375 | @param[in] Flags EFI_REDFISH_DISCOVER_FLAG
|
---|
376 |
|
---|
377 | @retval EFI_SUCCESS Target network interface is ready to use.
|
---|
378 | @retval EFI_UNSUPPORTED Target network interface is not ready to use.
|
---|
379 | **/
|
---|
380 | EFI_STATUS
|
---|
381 | ValidateTargetNetworkInterface (
|
---|
382 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,
|
---|
383 | IN EFI_REDFISH_DISCOVER_FLAG Flags
|
---|
384 | )
|
---|
385 | {
|
---|
386 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
387 |
|
---|
388 | if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) && (TargetNetworkInterface == NULL)) {
|
---|
389 | return EFI_UNSUPPORTED;
|
---|
390 | }
|
---|
391 |
|
---|
392 | if (TargetNetworkInterface == NULL) {
|
---|
393 | return EFI_SUCCESS; // Return EFI_SUCCESS if no network interface is specified.
|
---|
394 | }
|
---|
395 |
|
---|
396 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
397 | while (TRUE) {
|
---|
398 | if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {
|
---|
399 | break;
|
---|
400 | }
|
---|
401 |
|
---|
402 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
|
---|
403 | return EFI_UNSUPPORTED;
|
---|
404 | }
|
---|
405 |
|
---|
406 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
|
---|
407 | }
|
---|
408 |
|
---|
409 | if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
|
---|
410 | // Validate if UDP4/6 is supported on the given network interface.
|
---|
411 | // SSDP is not supported.
|
---|
412 |
|
---|
413 | return EFI_SUCCESS;
|
---|
414 | }
|
---|
415 |
|
---|
416 | if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == NULL) {
|
---|
417 | return EFI_UNSUPPORTED; // The required protocol on this network interface is not found.
|
---|
418 | }
|
---|
419 |
|
---|
420 | return EFI_SUCCESS;
|
---|
421 | }
|
---|
422 |
|
---|
423 | /**
|
---|
424 | This function returns number of network interface instance.
|
---|
425 |
|
---|
426 | @retval UINTN Number of network interface instances.
|
---|
427 | **/
|
---|
428 | UINTN
|
---|
429 | NumberOfNetworkInterface (
|
---|
430 | VOID
|
---|
431 | )
|
---|
432 | {
|
---|
433 | UINTN Num;
|
---|
434 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
435 |
|
---|
436 | if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
|
---|
437 | return 0;
|
---|
438 | }
|
---|
439 |
|
---|
440 | Num = 1;
|
---|
441 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
442 | while (TRUE) {
|
---|
443 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
|
---|
444 | break;
|
---|
445 | }
|
---|
446 |
|
---|
447 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
|
---|
448 | Num++;
|
---|
449 | }
|
---|
450 |
|
---|
451 | return Num;
|
---|
452 | }
|
---|
453 |
|
---|
454 | /**
|
---|
455 | This function checks the IP version supported on this
|
---|
456 | network interface.
|
---|
457 |
|
---|
458 | @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
|
---|
459 |
|
---|
460 | @retval TRUE Is IPv6, otherwise IPv4.
|
---|
461 |
|
---|
462 | **/
|
---|
463 | BOOLEAN
|
---|
464 | CheckIsIpVersion6 (
|
---|
465 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface
|
---|
466 | )
|
---|
467 | {
|
---|
468 | if (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) {
|
---|
469 | return TRUE;
|
---|
470 | }
|
---|
471 |
|
---|
472 | return FALSE;
|
---|
473 | }
|
---|
474 |
|
---|
475 | /**
|
---|
476 | This function discover Redfish service through SMBIOS host interface.
|
---|
477 |
|
---|
478 | @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
|
---|
479 |
|
---|
480 | @retval EFI_SUCCESS Redfish service is discovered through SMBIOS Host interface.
|
---|
481 | @retval Others Fail to discover Redfish service through SMBIOS host interface
|
---|
482 |
|
---|
483 | **/
|
---|
484 | EFI_STATUS
|
---|
485 | DiscoverRedfishHostInterface (
|
---|
486 | IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance
|
---|
487 | )
|
---|
488 | {
|
---|
489 | EFI_STATUS Status;
|
---|
490 | REDFISH_OVER_IP_PROTOCOL_DATA *Data;
|
---|
491 | REDFISH_INTERFACE_DATA *DeviceDescriptor;
|
---|
492 | CHAR8 UuidStr[sizeof "00000000-0000-0000-0000-000000000000" + 1];
|
---|
493 | CHAR16 Ipv6Str[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
|
---|
494 | CHAR8 RedfishServiceLocateStr[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
|
---|
495 | UINTN StrSize;
|
---|
496 | UINTN MacCompareStatus;
|
---|
497 | BOOLEAN IsHttps;
|
---|
498 |
|
---|
499 | Data = NULL;
|
---|
500 | DeviceDescriptor = NULL;
|
---|
501 |
|
---|
502 | if (mSmbios == NULL) {
|
---|
503 | Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios);
|
---|
504 | if (EFI_ERROR (Status)) {
|
---|
505 | return Status;
|
---|
506 | }
|
---|
507 | }
|
---|
508 |
|
---|
509 | Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
|
---|
510 | if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) {
|
---|
511 | //
|
---|
512 | // Check if we can reach out Redfish service using this network interface.
|
---|
513 | // Check with MAC address using Device Descriptor Data Device Type 04 and Type 05.
|
---|
514 | // Those two types of Redfish host interface device has MAC information.
|
---|
515 | //
|
---|
516 | if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
|
---|
517 | MacCompareStatus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6);
|
---|
518 | } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) {
|
---|
519 | MacCompareStatus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6);
|
---|
520 | } else {
|
---|
521 | return EFI_UNSUPPORTED;
|
---|
522 | }
|
---|
523 |
|
---|
524 | if (MacCompareStatus != 0) {
|
---|
525 | return EFI_UNSUPPORTED;
|
---|
526 | }
|
---|
527 |
|
---|
528 | Instance->HostAddrFormat = Data->HostIpAddressFormat;
|
---|
529 | if (Data->HostIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
|
---|
530 | IP4_COPY_ADDRESS ((VOID *)&Instance->HostIpAddress.v4, (VOID *)Data->HostIpAddress);
|
---|
531 | IP4_COPY_ADDRESS ((VOID *)&Instance->HostSubnetMask.v4, (VOID *)Data->HostIpMask);
|
---|
532 |
|
---|
533 | if (EFI_IP4_EQUAL (&Instance->HostIpAddress.v4, &mZeroIp4Addr)) {
|
---|
534 | DEBUG ((DEBUG_ERROR, "%a: invalid host IP address: ", __func__));
|
---|
535 | DumpIpv4Address (DEBUG_ERROR, &Instance->HostIpAddress.v4);
|
---|
536 | //
|
---|
537 | // Invalid IP address detected. Change address format to Unknown and use system default address.
|
---|
538 | //
|
---|
539 | Instance->HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
|
---|
540 | }
|
---|
541 |
|
---|
542 | if (!IP4_IS_VALID_NETMASK (NTOHL (EFI_IP4 (Instance->HostSubnetMask.v4)))) {
|
---|
543 | DEBUG ((DEBUG_ERROR, "%a: invalid subnet mask address: ", __func__));
|
---|
544 | DumpIpv4Address (DEBUG_ERROR, &Instance->HostSubnetMask.v4);
|
---|
545 | //
|
---|
546 | // Invalid subnet mast address detected. Change address format to Unknown and use system default address.
|
---|
547 | //
|
---|
548 | Instance->HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
|
---|
549 | }
|
---|
550 | } else if (Data->HostIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
|
---|
551 | IP6_COPY_ADDRESS ((VOID *)&Instance->HostIpAddress.v6, (VOID *)Data->HostIpAddress);
|
---|
552 | }
|
---|
553 |
|
---|
554 | if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
|
---|
555 | IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress);
|
---|
556 |
|
---|
557 | if (EFI_IP4_EQUAL (&Instance->TargetIpAddress.v4, &mZeroIp4Addr)) {
|
---|
558 | DEBUG ((DEBUG_ERROR, "%a: invalid service IP address: ", __func__));
|
---|
559 | DumpIpv4Address (DEBUG_ERROR, &Instance->TargetIpAddress.v4);
|
---|
560 | }
|
---|
561 | } else {
|
---|
562 | IP6_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v6, (VOID *)Data->RedfishServiceIpAddress);
|
---|
563 | }
|
---|
564 |
|
---|
565 | if (Instance->HostIntfValidation) {
|
---|
566 | DEBUG ((DEBUG_ERROR, "%a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported.\n", __func__));
|
---|
567 | Status = EFI_UNSUPPORTED;
|
---|
568 | } else {
|
---|
569 | //
|
---|
570 | // Add this instance to list without detail information of Redfish
|
---|
571 | // service.
|
---|
572 | //
|
---|
573 | IsHttps = FALSE;
|
---|
574 | if (Data->RedfishServiceIpPort == 443) {
|
---|
575 | IsHttps = TRUE;
|
---|
576 | }
|
---|
577 |
|
---|
578 | StrSize = sizeof (UuidStr);
|
---|
579 | AsciiSPrint (UuidStr, StrSize, "%g", &Data->ServiceUuid);
|
---|
580 | //
|
---|
581 | // Generate Redfish service location string.
|
---|
582 | //
|
---|
583 | if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
|
---|
584 | NetLibIp6ToStr ((IPv6_ADDRESS *)&Data->RedfishServiceIpAddress, Ipv6Str, sizeof (Ipv6Str));
|
---|
585 | if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
|
---|
586 | AsciiSPrintUnicodeFormat (
|
---|
587 | RedfishServiceLocateStr,
|
---|
588 | sizeof (RedfishServiceLocateStr),
|
---|
589 | L"%s",
|
---|
590 | Ipv6Str
|
---|
591 | );
|
---|
592 | } else {
|
---|
593 | AsciiSPrintUnicodeFormat (
|
---|
594 | RedfishServiceLocateStr,
|
---|
595 | sizeof (RedfishServiceLocateStr),
|
---|
596 | L"[%s]:%d",
|
---|
597 | Ipv6Str,
|
---|
598 | Data->RedfishServiceIpPort
|
---|
599 | );
|
---|
600 | }
|
---|
601 | } else {
|
---|
602 | if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
|
---|
603 | AsciiSPrint (
|
---|
604 | RedfishServiceLocateStr,
|
---|
605 | sizeof (RedfishServiceLocateStr),
|
---|
606 | "%d.%d.%d.%d",
|
---|
607 | Data->RedfishServiceIpAddress[0],
|
---|
608 | Data->RedfishServiceIpAddress[1],
|
---|
609 | Data->RedfishServiceIpAddress[2],
|
---|
610 | Data->RedfishServiceIpAddress[3]
|
---|
611 | );
|
---|
612 | } else {
|
---|
613 | AsciiSPrint (
|
---|
614 | RedfishServiceLocateStr,
|
---|
615 | sizeof (RedfishServiceLocateStr),
|
---|
616 | "%d.%d.%d.%d:%d",
|
---|
617 | Data->RedfishServiceIpAddress[0],
|
---|
618 | Data->RedfishServiceIpAddress[1],
|
---|
619 | Data->RedfishServiceIpAddress[2],
|
---|
620 | Data->RedfishServiceIpAddress[3],
|
---|
621 | Data->RedfishServiceIpPort
|
---|
622 | );
|
---|
623 | }
|
---|
624 | }
|
---|
625 |
|
---|
626 | Status = AddAndSignalNewRedfishService (
|
---|
627 | Instance,
|
---|
628 | NULL,
|
---|
629 | RedfishServiceLocateStr,
|
---|
630 | UuidStr,
|
---|
631 | NULL,
|
---|
632 | NULL,
|
---|
633 | NULL,
|
---|
634 | NULL,
|
---|
635 | IsHttps
|
---|
636 | );
|
---|
637 | }
|
---|
638 | }
|
---|
639 |
|
---|
640 | return Status;
|
---|
641 | }
|
---|
642 |
|
---|
643 | /**
|
---|
644 | The function adds a new found Redfish service to internal list and
|
---|
645 | notify client.
|
---|
646 |
|
---|
647 | @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
|
---|
648 | @param[in] RedfishVersion Redfish version.
|
---|
649 | @param[in] RedfishLocation Redfish location.
|
---|
650 | @param[in] Uuid Service UUID string.
|
---|
651 | @param[in] Os OS string.
|
---|
652 | @param[in] OsVer OS version string.
|
---|
653 | @param[in] Product Product string.
|
---|
654 | @param[in] ProductVer Product version string.
|
---|
655 | @param[in] UseHttps Redfish service requires secured connection.
|
---|
656 | @retval EFI_SUCCESS Redfish service is added to list successfully.
|
---|
657 |
|
---|
658 | **/
|
---|
659 | EFI_STATUS
|
---|
660 | AddAndSignalNewRedfishService (
|
---|
661 | IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance,
|
---|
662 | IN UINTN *RedfishVersion OPTIONAL,
|
---|
663 | IN CHAR8 *RedfishLocation OPTIONAL,
|
---|
664 | IN CHAR8 *Uuid OPTIONAL,
|
---|
665 | IN CHAR8 *Os OPTIONAL,
|
---|
666 | IN CHAR8 *OsVer OPTIONAL,
|
---|
667 | IN CHAR8 *Product OPTIONAL,
|
---|
668 | IN CHAR8 *ProductVer OPTIONAL,
|
---|
669 | IN BOOLEAN UseHttps
|
---|
670 | )
|
---|
671 | {
|
---|
672 | BOOLEAN NewFound;
|
---|
673 | BOOLEAN InfoRefresh;
|
---|
674 | BOOLEAN RestExOpened;
|
---|
675 | BOOLEAN DeleteRestEx;
|
---|
676 | EFI_STATUS Status;
|
---|
677 | EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredList;
|
---|
678 | EFI_REDFISH_DISCOVERED_INSTANCE *DiscoveredInstance;
|
---|
679 | CHAR16 *Char16Uuid;
|
---|
680 | EFI_REST_EX_PROTOCOL *RestEx;
|
---|
681 | EFI_REST_EX_HTTP_CONFIG_DATA *RestExHttpConfigData;
|
---|
682 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface;
|
---|
683 |
|
---|
684 | NewFound = TRUE;
|
---|
685 | InfoRefresh = FALSE;
|
---|
686 | Char16Uuid = NULL;
|
---|
687 | RestExOpened = FALSE;
|
---|
688 | DeleteRestEx = FALSE;
|
---|
689 |
|
---|
690 | DEBUG ((DEBUG_MANAGEABILITY, "%a:Add this instance to Redfish instance list.\n", __func__));
|
---|
691 |
|
---|
692 | if (Uuid != NULL) {
|
---|
693 | Char16Uuid = (CHAR16 *)AllocateZeroPool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
|
---|
694 | AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, Char16Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
|
---|
695 | }
|
---|
696 |
|
---|
697 | DiscoveredList = NULL;
|
---|
698 | DiscoveredInstance = NULL;
|
---|
699 | RestExHttpConfigData = NULL;
|
---|
700 |
|
---|
701 | NetworkInterface = Instance->NetworkInterface;
|
---|
702 | if (!IsListEmpty (&mRedfishInstanceList)) {
|
---|
703 | //
|
---|
704 | // Is this a duplicate redfish service.
|
---|
705 | //
|
---|
706 | DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
|
---|
707 | NewFound = FALSE;
|
---|
708 | do {
|
---|
709 | if ((Char16Uuid == NULL) || (DiscoveredList->Instance->Information.Uuid == NULL)) {
|
---|
710 | //
|
---|
711 | // Check if this Redfish instance already found using IP address.
|
---|
712 | //
|
---|
713 | if (!CheckIsIpVersion6 (NetworkInterface)) {
|
---|
714 | if (CompareMem (
|
---|
715 | (VOID *)&Instance->TargetIpAddress.v4,
|
---|
716 | (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v4,
|
---|
717 | sizeof (EFI_IPv4_ADDRESS)
|
---|
718 | ) == 0)
|
---|
719 | {
|
---|
720 | DiscoveredInstance = DiscoveredList->Instance;
|
---|
721 | if ((DiscoveredList->Instance->Information.Uuid == NULL) &&
|
---|
722 | (Char16Uuid != NULL))
|
---|
723 | {
|
---|
724 | InfoRefresh = TRUE;
|
---|
725 | DiscoveredInstance = DiscoveredList->Instance;
|
---|
726 | DEBUG ((DEBUG_MANAGEABILITY, "*** This Redfish Service information refresh ***\n"));
|
---|
727 | }
|
---|
728 |
|
---|
729 | break;
|
---|
730 | }
|
---|
731 | } else {
|
---|
732 | if (CompareMem (
|
---|
733 | (VOID *)&Instance->TargetIpAddress.v6,
|
---|
734 | (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v6,
|
---|
735 | sizeof (EFI_IPv6_ADDRESS)
|
---|
736 | ) == 0)
|
---|
737 | {
|
---|
738 | DiscoveredInstance = DiscoveredList->Instance;
|
---|
739 | break;
|
---|
740 | }
|
---|
741 | }
|
---|
742 | } else {
|
---|
743 | //
|
---|
744 | // Check if this Redfish instance already found using UUID.
|
---|
745 | //
|
---|
746 | if (StrCmp ((const CHAR16 *)Char16Uuid, (const CHAR16 *)DiscoveredList->Instance->Information.Uuid) == 0) {
|
---|
747 | DiscoveredInstance = DiscoveredList->Instance;
|
---|
748 | break;
|
---|
749 | }
|
---|
750 | }
|
---|
751 |
|
---|
752 | if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredList->NextInstance)) {
|
---|
753 | NewFound = TRUE;
|
---|
754 | break;
|
---|
755 | }
|
---|
756 |
|
---|
757 | DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredList->NextInstance);
|
---|
758 | } while (TRUE);
|
---|
759 | }
|
---|
760 |
|
---|
761 | if (NewFound || InfoRefresh) {
|
---|
762 | if (!InfoRefresh) {
|
---|
763 | DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_LIST));
|
---|
764 | if (DiscoveredList == NULL) {
|
---|
765 | return EFI_OUT_OF_RESOURCES;
|
---|
766 | }
|
---|
767 |
|
---|
768 | InitializeListHead (&DiscoveredList->NextInstance);
|
---|
769 | DiscoveredInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
|
---|
770 | if (DiscoveredInstance == NULL) {
|
---|
771 | FreePool ((VOID *)DiscoveredList);
|
---|
772 | return EFI_OUT_OF_RESOURCES;
|
---|
773 | }
|
---|
774 | }
|
---|
775 |
|
---|
776 | DEBUG ((DEBUG_MANAGEABILITY, "*** Redfish Service Information ***\n"));
|
---|
777 |
|
---|
778 | DiscoveredInstance->Information.UseHttps = UseHttps;
|
---|
779 | if (RedfishVersion != NULL) {
|
---|
780 | DiscoveredInstance->Information.RedfishVersion = *RedfishVersion;
|
---|
781 | DEBUG ((DEBUG_MANAGEABILITY, "Redfish service version: %d.\n", DiscoveredInstance->Information.RedfishVersion));
|
---|
782 | }
|
---|
783 |
|
---|
784 | if (RedfishLocation != NULL) {
|
---|
785 | DiscoveredInstance->Information.Location = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));
|
---|
786 | AsciiStrToUnicodeStrS ((const CHAR8 *)RedfishLocation, DiscoveredInstance->Information.Location, AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));
|
---|
787 | DEBUG ((DEBUG_MANAGEABILITY, "Redfish service location: %s.\n", DiscoveredInstance->Information.Location));
|
---|
788 | }
|
---|
789 |
|
---|
790 | if (Uuid != NULL) {
|
---|
791 | DiscoveredInstance->Information.Uuid = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
|
---|
792 | AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, DiscoveredInstance->Information.Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
|
---|
793 | DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
|
---|
794 | }
|
---|
795 |
|
---|
796 | if (Os != NULL) {
|
---|
797 | DiscoveredInstance->Information.Os = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));
|
---|
798 | AsciiStrToUnicodeStrS ((const CHAR8 *)Os, DiscoveredInstance->Information.Os, AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));
|
---|
799 | DEBUG ((DEBUG_MANAGEABILITY, "Redfish service OS: %s, Version:%s.\n", DiscoveredInstance->Information.Os, DiscoveredInstance->Information.OsVersion));
|
---|
800 | }
|
---|
801 |
|
---|
802 | if (OsVer != NULL) {
|
---|
803 | DiscoveredInstance->Information.OsVersion = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));
|
---|
804 | AsciiStrToUnicodeStrS ((const CHAR8 *)OsVer, DiscoveredInstance->Information.OsVersion, AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));
|
---|
805 | }
|
---|
806 |
|
---|
807 | if ((Product != NULL) && (ProductVer != NULL)) {
|
---|
808 | DiscoveredInstance->Information.Product = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));
|
---|
809 | AsciiStrToUnicodeStrS ((const CHAR8 *)Product, DiscoveredInstance->Information.Product, AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));
|
---|
810 | DiscoveredInstance->Information.ProductVer = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));
|
---|
811 | AsciiStrToUnicodeStrS ((const CHAR8 *)ProductVer, DiscoveredInstance->Information.ProductVer, AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));
|
---|
812 | DEBUG ((DEBUG_MANAGEABILITY, "Redfish service product: %s, Version:%s.\n", DiscoveredInstance->Information.Product, DiscoveredInstance->Information.ProductVer));
|
---|
813 | }
|
---|
814 |
|
---|
815 | if (RedfishLocation == NULL) {
|
---|
816 | // This is the Redfish reported from SMBIOS 42h
|
---|
817 | // without validation.
|
---|
818 |
|
---|
819 | IP4_COPY_ADDRESS ((VOID *)&DiscoveredInstance->Information.RedfishHostIpAddress.v4, (VOID *)&Instance->TargetIpAddress.v4);
|
---|
820 | }
|
---|
821 |
|
---|
822 | if (!InfoRefresh) {
|
---|
823 | DiscoveredList->Instance = DiscoveredInstance;
|
---|
824 | InsertTailList (&mRedfishInstanceList, &DiscoveredList->NextInstance);
|
---|
825 | }
|
---|
826 |
|
---|
827 | DiscoveredInstance->Status = EFI_SUCCESS;
|
---|
828 | } else {
|
---|
829 | if (DiscoveredList != NULL) {
|
---|
830 | DEBUG ((DEBUG_MANAGEABILITY, "*** This Redfish Service was already found ***\n"));
|
---|
831 | if (DiscoveredInstance->Information.Uuid != NULL) {
|
---|
832 | DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
|
---|
833 | } else {
|
---|
834 | DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: unknown.\n"));
|
---|
835 | }
|
---|
836 | }
|
---|
837 | }
|
---|
838 |
|
---|
839 | if (Char16Uuid != NULL) {
|
---|
840 | FreePool ((VOID *)Char16Uuid);
|
---|
841 | }
|
---|
842 |
|
---|
843 | Status = EFI_SUCCESS;
|
---|
844 | if (NewFound || InfoRefresh) {
|
---|
845 | //
|
---|
846 | // Build up EFI_REDFISH_DISCOVERED_LIST in token.
|
---|
847 | //
|
---|
848 | Instance->DiscoverToken->DiscoverList.NumberOfServiceFound = 1;
|
---|
849 | Instance->DiscoverToken->DiscoverList.RedfishInstances = DiscoveredInstance;
|
---|
850 | DiscoveredInstance->Status = EFI_SUCCESS;
|
---|
851 | if (!InfoRefresh) {
|
---|
852 | Status = CreateRestExInstance (Instance, Instance->DiscoverToken); // Create REST EX child.
|
---|
853 | if (EFI_ERROR (Status)) {
|
---|
854 | DEBUG ((DEBUG_ERROR, "%a:Can't create REST EX child instance.\n", __func__));
|
---|
855 | goto ON_EXIT;
|
---|
856 | }
|
---|
857 |
|
---|
858 | Status = gBS->OpenProtocol (
|
---|
859 | // Configure local host information.
|
---|
860 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
|
---|
861 | &gEfiRestExProtocolGuid,
|
---|
862 | (VOID **)&RestEx,
|
---|
863 | Instance->NetworkInterface->OpenDriverAgentHandle,
|
---|
864 | Instance->NetworkInterface->OpenDriverControllerHandle,
|
---|
865 | EFI_OPEN_PROTOCOL_BY_DRIVER
|
---|
866 | );
|
---|
867 | if (EFI_ERROR (Status)) {
|
---|
868 | DeleteRestEx = TRUE;
|
---|
869 | goto ERROR_EXIT;
|
---|
870 | }
|
---|
871 |
|
---|
872 | RestExOpened = TRUE;
|
---|
873 | RestExHttpConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));
|
---|
874 | if (RestExHttpConfigData == NULL) {
|
---|
875 | Status = EFI_OUT_OF_RESOURCES;
|
---|
876 | DeleteRestEx = TRUE;
|
---|
877 | goto EXIT_FREE_CONFIG_DATA;
|
---|
878 | }
|
---|
879 |
|
---|
880 | RestExHttpConfigData->SendReceiveTimeout = 5000;
|
---|
881 | RestExHttpConfigData->HttpConfigData.HttpVersion = HttpVersion11;
|
---|
882 | RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6 = CheckIsIpVersion6 (NetworkInterface);
|
---|
883 | if (RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6) {
|
---|
884 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));
|
---|
885 | if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node == NULL) {
|
---|
886 | Status = EFI_OUT_OF_RESOURCES;
|
---|
887 | goto EXIT_FREE_CONFIG_DATA;
|
---|
888 | }
|
---|
889 |
|
---|
890 | if (Instance->HostAddrFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
|
---|
891 | IP6_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node->LocalAddress, &Instance->HostIpAddress.v6);
|
---|
892 | }
|
---|
893 | } else {
|
---|
894 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));
|
---|
895 | if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node == NULL) {
|
---|
896 | Status = EFI_OUT_OF_RESOURCES;
|
---|
897 | goto EXIT_FREE_CONFIG_DATA;
|
---|
898 | }
|
---|
899 |
|
---|
900 | if (Instance->HostAddrFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
|
---|
901 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = FALSE;
|
---|
902 | IP4_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->LocalAddress, &Instance->HostIpAddress.v4);
|
---|
903 | IP4_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->LocalSubnet, &Instance->HostSubnetMask.v4);
|
---|
904 | } else {
|
---|
905 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = TRUE;
|
---|
906 | }
|
---|
907 | }
|
---|
908 |
|
---|
909 | Status = RestEx->Configure (
|
---|
910 | RestEx,
|
---|
911 | (EFI_REST_EX_CONFIG_DATA)(UINT8 *)RestExHttpConfigData
|
---|
912 | );
|
---|
913 | if (EFI_ERROR (Status)) {
|
---|
914 | DEBUG ((DEBUG_ERROR, "%a:REST EX configured..\n", __func__));
|
---|
915 | DeleteRestEx = TRUE;
|
---|
916 | goto EXIT_FREE_ALL;
|
---|
917 | }
|
---|
918 |
|
---|
919 | //
|
---|
920 | // Signal client, close REST EX before signaling client.
|
---|
921 | //
|
---|
922 | if (RestExOpened) {
|
---|
923 | gBS->CloseProtocol (
|
---|
924 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
|
---|
925 | &gEfiRestExProtocolGuid,
|
---|
926 | Instance->NetworkInterface->OpenDriverAgentHandle,
|
---|
927 | Instance->NetworkInterface->OpenDriverControllerHandle
|
---|
928 | );
|
---|
929 | RestExOpened = FALSE;
|
---|
930 | }
|
---|
931 | }
|
---|
932 |
|
---|
933 | Status = gBS->SignalEvent (Instance->DiscoverToken->Event);
|
---|
934 | if (EFI_ERROR (Status)) {
|
---|
935 | DEBUG ((DEBUG_ERROR, "%a:No event to signal!\n", __func__));
|
---|
936 | }
|
---|
937 | }
|
---|
938 |
|
---|
939 | EXIT_FREE_ALL:;
|
---|
940 | if ((RestExHttpConfigData != NULL) && (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node != NULL)) {
|
---|
941 | FreePool (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node);
|
---|
942 | }
|
---|
943 |
|
---|
944 | EXIT_FREE_CONFIG_DATA:;
|
---|
945 | if (RestExHttpConfigData != NULL) {
|
---|
946 | FreePool ((VOID *)RestExHttpConfigData);
|
---|
947 | }
|
---|
948 |
|
---|
949 | if (RestExOpened) {
|
---|
950 | gBS->CloseProtocol (
|
---|
951 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
|
---|
952 | &gEfiRestExProtocolGuid,
|
---|
953 | Instance->NetworkInterface->OpenDriverAgentHandle,
|
---|
954 | Instance->NetworkInterface->OpenDriverControllerHandle
|
---|
955 | );
|
---|
956 | }
|
---|
957 |
|
---|
958 | ERROR_EXIT:;
|
---|
959 | if (DeleteRestEx && RestExOpened) {
|
---|
960 | gBS->CloseProtocol (
|
---|
961 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
|
---|
962 | &gEfiRestExProtocolGuid,
|
---|
963 | Instance->NetworkInterface->OpenDriverAgentHandle,
|
---|
964 | Instance->NetworkInterface->OpenDriverControllerHandle
|
---|
965 | );
|
---|
966 | }
|
---|
967 |
|
---|
968 | ON_EXIT:;
|
---|
969 | return Status;
|
---|
970 | }
|
---|
971 |
|
---|
972 | /**
|
---|
973 | This function gets the subnet information of this network interface instance.
|
---|
974 | can discover Redfish service on it.
|
---|
975 |
|
---|
976 | @param[in] Instance EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.
|
---|
977 | @param[in] ImageHandle EFI Image handle request the network interface list.
|
---|
978 |
|
---|
979 | @retval EFI_SUCCESS
|
---|
980 |
|
---|
981 | **/
|
---|
982 | EFI_STATUS
|
---|
983 | NetworkInterfaceGetSubnetInfo (
|
---|
984 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance,
|
---|
985 | IN EFI_HANDLE ImageHandle
|
---|
986 | )
|
---|
987 | {
|
---|
988 | EFI_STATUS Status;
|
---|
989 | UINT32 ProtocolType;
|
---|
990 | UINT32 IPv6InfoIndex;
|
---|
991 | EFI_IP6_ADDRESS_INFO *ThisSubnetAddrInfoIPv6;
|
---|
992 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface;
|
---|
993 |
|
---|
994 | if (Instance->GotSubnetInfo) {
|
---|
995 | return EFI_SUCCESS;
|
---|
996 | }
|
---|
997 |
|
---|
998 | ProtocolType = Instance->NetworkProtocolType;
|
---|
999 | if ((gRequiredProtocol[ProtocolType].GetSubnetInfo != NULL) && (Instance->GotSubnetInfo == FALSE)) {
|
---|
1000 | Status = gRequiredProtocol[ProtocolType].GetSubnetInfo (
|
---|
1001 | ImageHandle,
|
---|
1002 | Instance
|
---|
1003 | );
|
---|
1004 | if (EFI_ERROR (Status)) {
|
---|
1005 | DEBUG ((DEBUG_ERROR, "%a:Failed to get Subnet infomation.\n", __func__));
|
---|
1006 | return Status;
|
---|
1007 | } else {
|
---|
1008 | DEBUG ((DEBUG_MANAGEABILITY, "%a:MAC address: %s\n", __func__, Instance->StrMacAddr));
|
---|
1009 | if (CheckIsIpVersion6 (Instance)) {
|
---|
1010 | if (Instance->SubnetAddrInfoIPv6Number == 0) {
|
---|
1011 | DEBUG ((DEBUG_ERROR, "%a: There is no Subnet infomation for IPv6 network interface.\n", __func__));
|
---|
1012 | return EFI_NOT_FOUND;
|
---|
1013 | }
|
---|
1014 |
|
---|
1015 | ThisSubnetAddrInfoIPv6 = Instance->SubnetAddrInfoIPv6; // First IPv6 address information.
|
---|
1016 | IP6_COPY_ADDRESS (&Instance->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
|
---|
1017 | Instance->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
|
---|
1018 | DEBUG ((
|
---|
1019 | DEBUG_MANAGEABILITY,
|
---|
1020 | " IPv6 Subnet ID:%d, Prefix length: %d.\n",
|
---|
1021 | ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
|
---|
1022 | ThisSubnetAddrInfoIPv6->PrefixLength
|
---|
1023 | )
|
---|
1024 | );
|
---|
1025 | //
|
---|
1026 | // If this is IPv6, then we may have to propagate network interface for IPv6 network scopes
|
---|
1027 | // according to the Ipv6 address information.
|
---|
1028 | //
|
---|
1029 | ThisSubnetAddrInfoIPv6++;
|
---|
1030 | for (IPv6InfoIndex = 0; IPv6InfoIndex < Instance->SubnetAddrInfoIPv6Number - 1; IPv6InfoIndex++) {
|
---|
1031 | //
|
---|
1032 | // Build up additional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances.
|
---|
1033 | //
|
---|
1034 | NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));
|
---|
1035 | if (NewNetworkInterface != NULL) {
|
---|
1036 | CopyMem ((VOID *)NewNetworkInterface, (VOID *)Instance, sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); // Clone information of first instance.
|
---|
1037 | IP6_COPY_ADDRESS (&NewNetworkInterface->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
|
---|
1038 | NewNetworkInterface->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
|
---|
1039 | NewNetworkInterface->GotSubnetInfo = TRUE;
|
---|
1040 | InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NewNetworkInterface->Entry);
|
---|
1041 | ThisSubnetAddrInfoIPv6++;
|
---|
1042 | mNumNetworkInterface++;
|
---|
1043 | DEBUG ((
|
---|
1044 | DEBUG_MANAGEABILITY,
|
---|
1045 | " IPv6 Subnet ID:%d, Prefix length: %d.\n",
|
---|
1046 | ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
|
---|
1047 | ThisSubnetAddrInfoIPv6->PrefixLength
|
---|
1048 | )
|
---|
1049 | );
|
---|
1050 | } else {
|
---|
1051 | return EFI_OUT_OF_RESOURCES;
|
---|
1052 | }
|
---|
1053 | }
|
---|
1054 | } else {
|
---|
1055 | DEBUG ((
|
---|
1056 | DEBUG_MANAGEABILITY,
|
---|
1057 | " IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d.\n",
|
---|
1058 | Instance->SubnetAddr.v4.Addr[0],
|
---|
1059 | Instance->SubnetAddr.v4.Addr[1],
|
---|
1060 | Instance->SubnetAddr.v4.Addr[2],
|
---|
1061 | Instance->SubnetAddr.v4.Addr[3],
|
---|
1062 | Instance->SubnetMask.v4.Addr[0],
|
---|
1063 | Instance->SubnetMask.v4.Addr[1],
|
---|
1064 | Instance->SubnetMask.v4.Addr[2],
|
---|
1065 | Instance->SubnetMask.v4.Addr[3]
|
---|
1066 | ));
|
---|
1067 | }
|
---|
1068 | }
|
---|
1069 | }
|
---|
1070 |
|
---|
1071 | Instance->GotSubnetInfo = TRUE; // Only try to get Subnet Info once.
|
---|
1072 | return EFI_SUCCESS;
|
---|
1073 | }
|
---|
1074 |
|
---|
1075 | /**
|
---|
1076 | This function gets the network interface list which Redfish discover protocol
|
---|
1077 | can discover Redfish service on it.
|
---|
1078 |
|
---|
1079 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
|
---|
1080 | @param[in] ImageHandle EFI Image handle request the network interface list,
|
---|
1081 | @param[out] NumberOfNetworkIntfs Number of network interfaces can do Redfish service discovery.
|
---|
1082 | @param[out] NetworkIntfInstances Network interface instances. It's an array of instance. The number of entries
|
---|
1083 | in array is indicated by NumberOfNetworkIntfs.
|
---|
1084 | Caller has to release the memory
|
---|
1085 | allocated by Redfish discover protocol.
|
---|
1086 |
|
---|
1087 | @retval EFI_SUCCESS The information of network interface is returned in NumberOfNetworkIntfs and
|
---|
1088 | NetworkIntfInstances.
|
---|
1089 | @retval Others Fail to return the information of network interface.
|
---|
1090 |
|
---|
1091 | **/
|
---|
1092 | EFI_STATUS
|
---|
1093 | EFIAPI
|
---|
1094 | RedfishServiceGetNetworkInterface (
|
---|
1095 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
|
---|
1096 | IN EFI_HANDLE ImageHandle,
|
---|
1097 | OUT UINTN *NumberOfNetworkIntfs,
|
---|
1098 | OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances
|
---|
1099 | )
|
---|
1100 | {
|
---|
1101 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn;
|
---|
1102 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;
|
---|
1103 | EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
|
---|
1104 |
|
---|
1105 | if ((This == NULL) || (NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) ||
|
---|
1106 | (ImageHandle == NULL))
|
---|
1107 | {
|
---|
1108 | return EFI_INVALID_PARAMETER;
|
---|
1109 | }
|
---|
1110 |
|
---|
1111 | *NumberOfNetworkIntfs = 0;
|
---|
1112 | *NetworkIntfInstances = NULL;
|
---|
1113 |
|
---|
1114 | if (IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
|
---|
1115 | return EFI_NOT_FOUND;
|
---|
1116 | }
|
---|
1117 |
|
---|
1118 | RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (This);
|
---|
1119 |
|
---|
1120 | //
|
---|
1121 | // Check the new found network interface.
|
---|
1122 | //
|
---|
1123 | if (RestExInstance->NetworkInterfaceInstances != NULL) {
|
---|
1124 | FreePool (RestExInstance->NetworkInterfaceInstances);
|
---|
1125 | RestExInstance->NetworkInterfaceInstances = NULL;
|
---|
1126 | }
|
---|
1127 |
|
---|
1128 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface);
|
---|
1129 | if (ThisNetworkInterface == NULL) {
|
---|
1130 | return EFI_OUT_OF_RESOURCES;
|
---|
1131 | }
|
---|
1132 |
|
---|
1133 | *NetworkIntfInstances = ThisNetworkInterface;
|
---|
1134 |
|
---|
1135 | RestExInstance->NetworkInterfaceInstances = ThisNetworkInterface;
|
---|
1136 | RestExInstance->NumberOfNetworkInterfaces = 0;
|
---|
1137 |
|
---|
1138 | ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
1139 | while (TRUE) {
|
---|
1140 | ThisNetworkInterface->IsIpv6 = FALSE;
|
---|
1141 | if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {
|
---|
1142 | ThisNetworkInterface->IsIpv6 = TRUE;
|
---|
1143 | }
|
---|
1144 |
|
---|
1145 | CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize);
|
---|
1146 | NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info.
|
---|
1147 | if (!ThisNetworkInterface->IsIpv6) {
|
---|
1148 | IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information.
|
---|
1149 | } else {
|
---|
1150 | IP6_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v6, &ThisNetworkInterfaceIntn->SubnetAddr.v6); // IPv6 subnet information in IPv6 address information.
|
---|
1151 | }
|
---|
1152 |
|
---|
1153 | ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength;
|
---|
1154 | ThisNetworkInterface->VlanId = ThisNetworkInterfaceIntn->VlanId;
|
---|
1155 | RestExInstance->NumberOfNetworkInterfaces++;
|
---|
1156 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {
|
---|
1157 | break;
|
---|
1158 | }
|
---|
1159 |
|
---|
1160 | ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
|
---|
1161 | ThisNetworkInterface++;
|
---|
1162 | }
|
---|
1163 |
|
---|
1164 | *NumberOfNetworkIntfs = RestExInstance->NumberOfNetworkInterfaces;
|
---|
1165 |
|
---|
1166 | return EFI_SUCCESS;
|
---|
1167 | }
|
---|
1168 |
|
---|
1169 | /**
|
---|
1170 | This function acquires Redfish services by discovering static Redfish setting
|
---|
1171 | according to Redfish Host Interface or through SSDP. Returns a list of EFI
|
---|
1172 | handles in EFI_REDFISH_DISCOVERED_LIST. Each of EFI handle has corresponding
|
---|
1173 | EFI REST EX instance installed on it. Each REST EX instance is a child instance which
|
---|
1174 | created through EFI REST EX service protocol for communicating with specific
|
---|
1175 | Redfish service.
|
---|
1176 |
|
---|
1177 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
|
---|
1178 | @param[in] ImageHandle EFI image owns these Redfish service instances.
|
---|
1179 | @param[in] TargetNetworkInterface Target network interface to do the discovery.
|
---|
1180 | NULL means discover Redfish service on all network interfaces on platform.
|
---|
1181 | @param[in] Flags Redfish service discover flags.
|
---|
1182 | @param[in] Token EFI_REDFISH_DISCOVERED_TOKEN instance.
|
---|
1183 | The memory of EFI_REDFISH_DISCOVERED_LIST and the strings in
|
---|
1184 | EFI_REDFISH_DISCOVERED_INFORMATION are all allocated by Acquire()
|
---|
1185 | and must be freed when caller invoke Release().
|
---|
1186 |
|
---|
1187 | @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned.
|
---|
1188 | @retval EFI_INVALID_PARAMETERS ImageHandle == NULL, Flags == 0, Token == NULL, Token->Timeout > 5,
|
---|
1189 | or Token->Event == NULL.
|
---|
1190 | @retval Others Fail acquire Redfish services.
|
---|
1191 |
|
---|
1192 | **/
|
---|
1193 | EFI_STATUS
|
---|
1194 | EFIAPI
|
---|
1195 | RedfishServiceAcquireService (
|
---|
1196 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
|
---|
1197 | IN EFI_HANDLE ImageHandle,
|
---|
1198 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,
|
---|
1199 | IN EFI_REDFISH_DISCOVER_FLAG Flags,
|
---|
1200 | IN EFI_REDFISH_DISCOVERED_TOKEN *Token
|
---|
1201 | )
|
---|
1202 | {
|
---|
1203 | EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance;
|
---|
1204 | EFI_STATUS Status1;
|
---|
1205 | BOOLEAN NewInstance;
|
---|
1206 | UINTN NumNetworkInterfaces;
|
---|
1207 | UINTN NetworkInterfacesIndex;
|
---|
1208 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterfaceInternal;
|
---|
1209 |
|
---|
1210 | DEBUG ((DEBUG_MANAGEABILITY, "%a:Entry.\n", __func__));
|
---|
1211 |
|
---|
1212 | //
|
---|
1213 | // Validate parameters.
|
---|
1214 | //
|
---|
1215 | if ((ImageHandle == NULL) || (Token == NULL) || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) {
|
---|
1216 | DEBUG ((DEBUG_ERROR, "%a:Invalid parameters.\n", __func__));
|
---|
1217 | return EFI_INVALID_PARAMETER;
|
---|
1218 | }
|
---|
1219 |
|
---|
1220 | //
|
---|
1221 | // Validate target network interface.
|
---|
1222 | //
|
---|
1223 | if (EFI_ERROR (ValidateTargetNetworkInterface (TargetNetworkInterface, Flags))) {
|
---|
1224 | return EFI_UNSUPPORTED;
|
---|
1225 | }
|
---|
1226 |
|
---|
1227 | if (TargetNetworkInterface != NULL) {
|
---|
1228 | TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface);
|
---|
1229 | NumNetworkInterfaces = 1;
|
---|
1230 | } else {
|
---|
1231 | TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
1232 | NumNetworkInterfaces = NumberOfNetworkInterface ();
|
---|
1233 | if (NumNetworkInterfaces == 0) {
|
---|
1234 | DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __func__));
|
---|
1235 | return EFI_UNSUPPORTED;
|
---|
1236 | }
|
---|
1237 | }
|
---|
1238 |
|
---|
1239 | for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex++) {
|
---|
1240 | Status1 = EFI_SUCCESS;
|
---|
1241 | NewInstance = FALSE;
|
---|
1242 | Instance = GetInstanceByOwner (ImageHandle, TargetNetworkInterfaceInternal, Flags & ~EFI_REDFISH_DISCOVER_VALIDATION); // Check if we can re-use previous instance.
|
---|
1243 | if (Instance == NULL) {
|
---|
1244 | DEBUG ((DEBUG_MANAGEABILITY, "%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __func__));
|
---|
1245 | Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE));
|
---|
1246 | if (Instance == NULL) {
|
---|
1247 | DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __func__));
|
---|
1248 | return EFI_OUT_OF_RESOURCES;
|
---|
1249 | }
|
---|
1250 |
|
---|
1251 | InitializeListHead (&Instance->Entry);
|
---|
1252 | Instance->Owner = ImageHandle;
|
---|
1253 | Instance->DiscoverFlags = Flags & ~EFI_REDFISH_DISCOVER_VALIDATION;
|
---|
1254 | Instance->NetworkInterface = TargetNetworkInterfaceInternal;
|
---|
1255 | //
|
---|
1256 | // Get subnet information in case subnet information is not set because
|
---|
1257 | // RedfishServiceGetNetworkInterfaces hasn't been called yet.
|
---|
1258 | //
|
---|
1259 | NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle);
|
---|
1260 | NewInstance = TRUE;
|
---|
1261 | }
|
---|
1262 |
|
---|
1263 | if (TargetNetworkInterfaceInternal->StrMacAddr != NULL) {
|
---|
1264 | DEBUG ((DEBUG_MANAGEABILITY, "%a:Acquire Redfish service on network interface MAC address:%s.\n", __func__, TargetNetworkInterfaceInternal->StrMacAddr));
|
---|
1265 | } else {
|
---|
1266 | DEBUG ((DEBUG_MANAGEABILITY, "%a:WARNING: No MAC address on this network interface.\n", __func__));
|
---|
1267 | }
|
---|
1268 |
|
---|
1269 | Instance->DiscoverToken = Token; // Always use the latest Token passed by caller.
|
---|
1270 | if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) {
|
---|
1271 | DEBUG ((DEBUG_MANAGEABILITY, "%a:Redfish HOST interface discovery.\n", __func__));
|
---|
1272 | Instance->HostIntfValidation = FALSE;
|
---|
1273 | if ((Flags & EFI_REDFISH_DISCOVER_VALIDATION) != 0) {
|
---|
1274 | Instance->HostIntfValidation = TRUE;
|
---|
1275 | }
|
---|
1276 |
|
---|
1277 | Status1 = DiscoverRedfishHostInterface (Instance); // Discover Redfish service through Redfish Host Interface.
|
---|
1278 | }
|
---|
1279 |
|
---|
1280 | if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
|
---|
1281 | DEBUG ((DEBUG_ERROR, "%a:Redfish service discovery through SSDP is not supported\n", __func__));
|
---|
1282 | return EFI_UNSUPPORTED;
|
---|
1283 | } else {
|
---|
1284 | if (EFI_ERROR (Status1)) {
|
---|
1285 | if (NewInstance) {
|
---|
1286 | FreePool ((VOID *)Instance);
|
---|
1287 | }
|
---|
1288 |
|
---|
1289 | DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1));
|
---|
1290 | } else {
|
---|
1291 | if (NewInstance) {
|
---|
1292 | InsertTailList (&mRedfishDiscoverList, &Instance->Entry);
|
---|
1293 | }
|
---|
1294 | }
|
---|
1295 | }
|
---|
1296 |
|
---|
1297 | if (TargetNetworkInterface == NULL) {
|
---|
1298 | //
|
---|
1299 | // Discover Redfish services on all of network interfaces.
|
---|
1300 | //
|
---|
1301 | TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &TargetNetworkInterfaceInternal->Entry);
|
---|
1302 | }
|
---|
1303 | }
|
---|
1304 |
|
---|
1305 | return EFI_SUCCESS;
|
---|
1306 | }
|
---|
1307 |
|
---|
1308 | /**
|
---|
1309 | This function aborts Redfish service discovery on the given network interface.
|
---|
1310 |
|
---|
1311 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
|
---|
1312 | @param[in] TargetNetworkInterface Target network interface to do the discovery.
|
---|
1313 |
|
---|
1314 | @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned.
|
---|
1315 | @retval Others Fail to abort Redfish service discovery.
|
---|
1316 |
|
---|
1317 | **/
|
---|
1318 | EFI_STATUS
|
---|
1319 | EFIAPI
|
---|
1320 | RedfishServiceAbortAcquire (
|
---|
1321 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
|
---|
1322 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface OPTIONAL
|
---|
1323 | )
|
---|
1324 | {
|
---|
1325 | // This function is used to abort Redfish service discovery through SSDP
|
---|
1326 | // on the network interface. SSDP is optionally suppoted by EFI_REDFISH_DISCOVER_PROTOCOL,
|
---|
1327 | // we dont have implementation for SSDP now.
|
---|
1328 |
|
---|
1329 | return EFI_UNSUPPORTED;
|
---|
1330 | }
|
---|
1331 |
|
---|
1332 | /**
|
---|
1333 | This function releases Redfish services found by RedfishServiceAcquire().
|
---|
1334 |
|
---|
1335 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
|
---|
1336 | @param[in] InstanceList The Redfish service to release.
|
---|
1337 |
|
---|
1338 | @retval EFI_SUCCESS REST EX instances of discovered Redfish are released.
|
---|
1339 | @retval Others Fail to remove the entry
|
---|
1340 |
|
---|
1341 | **/
|
---|
1342 | EFI_STATUS
|
---|
1343 | EFIAPI
|
---|
1344 | RedfishServiceReleaseService (
|
---|
1345 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
|
---|
1346 | IN EFI_REDFISH_DISCOVERED_LIST *InstanceList
|
---|
1347 | )
|
---|
1348 | {
|
---|
1349 | UINTN NumService;
|
---|
1350 | BOOLEAN AnyFailRelease;
|
---|
1351 | EFI_REDFISH_DISCOVERED_INSTANCE *ThisRedfishInstance;
|
---|
1352 | EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredRedfishInstance;
|
---|
1353 |
|
---|
1354 | if (IsListEmpty (&mRedfishInstanceList)) {
|
---|
1355 | DEBUG ((DEBUG_ERROR, "%a:No any discovered Redfish service.\n", __func__));
|
---|
1356 | return EFI_NOT_FOUND;
|
---|
1357 | }
|
---|
1358 |
|
---|
1359 | AnyFailRelease = FALSE;
|
---|
1360 | ThisRedfishInstance = InstanceList->RedfishInstances;
|
---|
1361 | for (NumService = 0; NumService < InstanceList->NumberOfServiceFound; NumService++) {
|
---|
1362 | DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
|
---|
1363 | do {
|
---|
1364 | if (DiscoveredRedfishInstance->Instance == ThisRedfishInstance) {
|
---|
1365 | RemoveEntryList (&DiscoveredRedfishInstance->NextInstance);
|
---|
1366 | if (ThisRedfishInstance->Information.Location != NULL) {
|
---|
1367 | FreePool (ThisRedfishInstance->Information.Location);
|
---|
1368 | }
|
---|
1369 |
|
---|
1370 | if (ThisRedfishInstance->Information.Uuid != NULL) {
|
---|
1371 | FreePool (ThisRedfishInstance->Information.Uuid);
|
---|
1372 | }
|
---|
1373 |
|
---|
1374 | if (ThisRedfishInstance->Information.Os != NULL) {
|
---|
1375 | FreePool (ThisRedfishInstance->Information.Os);
|
---|
1376 | }
|
---|
1377 |
|
---|
1378 | if (ThisRedfishInstance->Information.OsVersion != NULL) {
|
---|
1379 | FreePool (ThisRedfishInstance->Information.OsVersion);
|
---|
1380 | }
|
---|
1381 |
|
---|
1382 | if (ThisRedfishInstance->Information.Product != NULL) {
|
---|
1383 | FreePool (ThisRedfishInstance->Information.Product);
|
---|
1384 | }
|
---|
1385 |
|
---|
1386 | if (ThisRedfishInstance->Information.ProductVer != NULL) {
|
---|
1387 | FreePool (ThisRedfishInstance->Information.ProductVer);
|
---|
1388 | }
|
---|
1389 |
|
---|
1390 | FreePool ((VOID *)ThisRedfishInstance);
|
---|
1391 | goto ReleaseNext;
|
---|
1392 | }
|
---|
1393 |
|
---|
1394 | if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance)) {
|
---|
1395 | break;
|
---|
1396 | }
|
---|
1397 |
|
---|
1398 | DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance);
|
---|
1399 | } while (TRUE);
|
---|
1400 |
|
---|
1401 | AnyFailRelease = TRUE;
|
---|
1402 | ReleaseNext:;
|
---|
1403 | //
|
---|
1404 | // Release next discovered Redfish Service.
|
---|
1405 | //
|
---|
1406 | ThisRedfishInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)((UINT8 *)ThisRedfishInstance + sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
|
---|
1407 | }
|
---|
1408 |
|
---|
1409 | if (AnyFailRelease) {
|
---|
1410 | return EFI_NOT_FOUND;
|
---|
1411 | } else {
|
---|
1412 | return EFI_SUCCESS;
|
---|
1413 | }
|
---|
1414 | }
|
---|
1415 |
|
---|
1416 | /**
|
---|
1417 | This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the
|
---|
1418 | given network interface.
|
---|
1419 |
|
---|
1420 |
|
---|
1421 | @param[in] ControllerHandle MAC address of this network interface.
|
---|
1422 | @param[in] NetworkProtocolType Network protocol type.
|
---|
1423 | @param[out] IsNewInstance BOOLEAN means new instance or not.
|
---|
1424 | @param[out] NetworkInterface Pointer to to EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL.
|
---|
1425 |
|
---|
1426 | @retval EFI_STATUS
|
---|
1427 | **/
|
---|
1428 | EFI_STATUS
|
---|
1429 | CreateRedfishDiscoverNetworkInterface (
|
---|
1430 | IN EFI_HANDLE ControllerHandle,
|
---|
1431 | IN UINT32 NetworkProtocolType,
|
---|
1432 | OUT BOOLEAN *IsNewInstance,
|
---|
1433 | OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL **NetworkInterface
|
---|
1434 | )
|
---|
1435 | {
|
---|
1436 | EFI_MAC_ADDRESS MacAddress;
|
---|
1437 | UINTN HwAddressSize;
|
---|
1438 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
1439 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface;
|
---|
1440 |
|
---|
1441 | NetLibGetMacAddress (ControllerHandle, &MacAddress, &HwAddressSize);
|
---|
1442 | NewNetworkInterface = NULL;
|
---|
1443 | *IsNewInstance = TRUE;
|
---|
1444 | if (!IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
|
---|
1445 | //
|
---|
1446 | // Check if this instance already exist.
|
---|
1447 | //
|
---|
1448 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
1449 | if (ThisNetworkInterface != NULL) {
|
---|
1450 | while (TRUE) {
|
---|
1451 | if ((CompareMem ((CONST VOID *)&ThisNetworkInterface->MacAddress.Addr, (CONST VOID *)&MacAddress.Addr, HwAddressSize) == 0) &&
|
---|
1452 | (ThisNetworkInterface->NetworkProtocolType == NetworkProtocolType))
|
---|
1453 | {
|
---|
1454 | NewNetworkInterface = ThisNetworkInterface;
|
---|
1455 | *IsNewInstance = FALSE;
|
---|
1456 | break;
|
---|
1457 | }
|
---|
1458 |
|
---|
1459 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
|
---|
1460 | NewNetworkInterface = NULL;
|
---|
1461 | break;
|
---|
1462 | }
|
---|
1463 |
|
---|
1464 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
|
---|
1465 | }
|
---|
1466 | }
|
---|
1467 | }
|
---|
1468 |
|
---|
1469 | if (NewNetworkInterface == NULL) {
|
---|
1470 | //
|
---|
1471 | // Create a new instance.
|
---|
1472 | //
|
---|
1473 | NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));
|
---|
1474 | if (NewNetworkInterface == NULL) {
|
---|
1475 | return EFI_OUT_OF_RESOURCES;
|
---|
1476 | }
|
---|
1477 |
|
---|
1478 | NewNetworkInterface->HwAddressSize = HwAddressSize;
|
---|
1479 | CopyMem (&NewNetworkInterface->MacAddress.Addr, &MacAddress.Addr, NewNetworkInterface->HwAddressSize);
|
---|
1480 | NetLibGetMacString (ControllerHandle, NULL, &NewNetworkInterface->StrMacAddr);
|
---|
1481 | NewNetworkInterface->VlanId = NetLibGetVlanId (ControllerHandle);
|
---|
1482 | }
|
---|
1483 |
|
---|
1484 | *NetworkInterface = NewNetworkInterface;
|
---|
1485 | return EFI_SUCCESS;
|
---|
1486 | }
|
---|
1487 |
|
---|
1488 | /**
|
---|
1489 | This function destroy network interface
|
---|
1490 |
|
---|
1491 |
|
---|
1492 | @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.
|
---|
1493 |
|
---|
1494 | @retval EFI_STATUS
|
---|
1495 | **/
|
---|
1496 | EFI_STATUS
|
---|
1497 | DestroyRedfishNetworkInterface (
|
---|
1498 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface
|
---|
1499 | )
|
---|
1500 | {
|
---|
1501 | EFI_STATUS Status;
|
---|
1502 |
|
---|
1503 | Status = gBS->UninstallProtocolInterface (
|
---|
1504 | ThisNetworkInterface->OpenDriverControllerHandle,
|
---|
1505 | gRequiredProtocol[ThisNetworkInterface->NetworkProtocolType].DiscoveredProtocolGuid,
|
---|
1506 | &ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId
|
---|
1507 | );
|
---|
1508 | RemoveEntryList (&ThisNetworkInterface->Entry);
|
---|
1509 | mNumNetworkInterface--;
|
---|
1510 | FreePool (ThisNetworkInterface);
|
---|
1511 | return Status;
|
---|
1512 | }
|
---|
1513 |
|
---|
1514 | /**
|
---|
1515 | Tests to see if the required protocols are provided on the given
|
---|
1516 | controller handle.
|
---|
1517 |
|
---|
1518 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
1519 | @param[in] ControllerHandle The handle of the controller to test. This handle
|
---|
1520 | must support a protocol interface that supplies
|
---|
1521 | an I/O abstraction to the driver.
|
---|
1522 | @retval EFI_SUCCESS One of required protocol is found.
|
---|
1523 | @retval EFI_UNSUPPORTED None of required protocol is found.
|
---|
1524 | **/
|
---|
1525 | EFI_STATUS
|
---|
1526 | TestForRequiredProtocols (
|
---|
1527 | IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
---|
1528 | IN EFI_HANDLE ControllerHandle
|
---|
1529 | )
|
---|
1530 | {
|
---|
1531 | UINT32 *Id;
|
---|
1532 | UINTN Index;
|
---|
1533 | EFI_STATUS Status;
|
---|
1534 | UINTN ListCount;
|
---|
1535 |
|
---|
1536 | ListCount = (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
|
---|
1537 | for (Index = 0; Index < ListCount; Index++) {
|
---|
1538 | Status = gBS->OpenProtocol (
|
---|
1539 | ControllerHandle,
|
---|
1540 | gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
|
---|
1541 | NULL,
|
---|
1542 | This->DriverBindingHandle,
|
---|
1543 | ControllerHandle,
|
---|
1544 | EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
---|
1545 | );
|
---|
1546 | if (!EFI_ERROR (Status)) {
|
---|
1547 | Status = gBS->OpenProtocol (
|
---|
1548 | ControllerHandle,
|
---|
1549 | gRequiredProtocol[Index].DiscoveredProtocolGuid,
|
---|
1550 | (VOID **)&Id,
|
---|
1551 | This->DriverBindingHandle,
|
---|
1552 | ControllerHandle,
|
---|
1553 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
1554 | );
|
---|
1555 | if (EFI_ERROR (Status)) {
|
---|
1556 | if (Index == ListCount - 1) {
|
---|
1557 | DEBUG ((DEBUG_ERROR, "%a: all required protocols are found on this controller handle: %p.\n", __func__, ControllerHandle));
|
---|
1558 | return EFI_SUCCESS;
|
---|
1559 | }
|
---|
1560 | }
|
---|
1561 | }
|
---|
1562 | }
|
---|
1563 |
|
---|
1564 | return EFI_UNSUPPORTED;
|
---|
1565 | }
|
---|
1566 |
|
---|
1567 | /**
|
---|
1568 | Build up network interface and create corresponding service through the given
|
---|
1569 | controller handle.
|
---|
1570 |
|
---|
1571 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
1572 | @param[in] ControllerHandle The handle of the controller to test. This handle
|
---|
1573 | must support a protocol interface that supplies
|
---|
1574 | an I/O abstraction to the driver.
|
---|
1575 | @retval EFI_SUCCESS One of required protocol is found.
|
---|
1576 | @retval EFI_UNSUPPORTED None of required protocol is found.
|
---|
1577 | @retval EFI_UNSUPPORTED Failed to build up network interface.
|
---|
1578 | **/
|
---|
1579 | EFI_STATUS
|
---|
1580 | BuildupNetworkInterface (
|
---|
1581 | IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
---|
1582 | IN EFI_HANDLE ControllerHandle
|
---|
1583 | )
|
---|
1584 | {
|
---|
1585 | UINT32 *Id;
|
---|
1586 | UINT32 Index;
|
---|
1587 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface;
|
---|
1588 | BOOLEAN IsNew;
|
---|
1589 | EFI_STATUS Status;
|
---|
1590 | VOID *TempInterface;
|
---|
1591 | VOID **Interface;
|
---|
1592 | UINT32 *ProtocolDiscoverIdPtr;
|
---|
1593 | EFI_HANDLE OpenDriverAgentHandle;
|
---|
1594 | EFI_HANDLE OpenDriverControllerHandle;
|
---|
1595 | EFI_HANDLE *HandleOfProtocolInterfacePtr;
|
---|
1596 | EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
|
---|
1597 | EFI_TPL OldTpl;
|
---|
1598 | BOOLEAN NewNetworkInterfaceInstalled;
|
---|
1599 |
|
---|
1600 | NewNetworkInterfaceInstalled = FALSE;
|
---|
1601 | Index = 0;
|
---|
1602 | do {
|
---|
1603 | Status = gBS->OpenProtocol (
|
---|
1604 | // Already in list?
|
---|
1605 | ControllerHandle,
|
---|
1606 | gRequiredProtocol[Index].DiscoveredProtocolGuid,
|
---|
1607 | (VOID **)&Id,
|
---|
1608 | This->DriverBindingHandle,
|
---|
1609 | ControllerHandle,
|
---|
1610 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
1611 | );
|
---|
1612 | if (!EFI_ERROR (Status)) {
|
---|
1613 | Index++;
|
---|
1614 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
|
---|
1615 | break;
|
---|
1616 | }
|
---|
1617 |
|
---|
1618 | continue;
|
---|
1619 | }
|
---|
1620 |
|
---|
1621 | Status = gBS->OpenProtocol (
|
---|
1622 | ControllerHandle,
|
---|
1623 | gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
|
---|
1624 | &TempInterface,
|
---|
1625 | This->DriverBindingHandle,
|
---|
1626 | ControllerHandle,
|
---|
1627 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
1628 | );
|
---|
1629 | if (EFI_ERROR (Status)) {
|
---|
1630 | Index++;
|
---|
1631 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
|
---|
1632 | break;
|
---|
1633 | }
|
---|
1634 |
|
---|
1635 | continue;
|
---|
1636 | }
|
---|
1637 |
|
---|
1638 | if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
|
---|
1639 | OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
|
---|
1640 | Status = CreateRedfishDiscoverNetworkInterface (ControllerHandle, gRequiredProtocol[Index].ProtocolType, &IsNew, &NetworkInterface);
|
---|
1641 | if (EFI_ERROR (Status)) {
|
---|
1642 | gBS->RestoreTPL (OldTpl);
|
---|
1643 | return Status;
|
---|
1644 | }
|
---|
1645 |
|
---|
1646 | NetworkInterface->NetworkProtocolType = gRequiredProtocol[Index].ProtocolType;
|
---|
1647 | NetworkInterface->OpenDriverAgentHandle = This->DriverBindingHandle;
|
---|
1648 | NetworkInterface->OpenDriverControllerHandle = ControllerHandle;
|
---|
1649 | CopyGuid (&NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid, gRequiredProtocol[Index].RequiredProtocolGuid);
|
---|
1650 | CopyGuid (&NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolServiceGuid, gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid);
|
---|
1651 | ProtocolDiscoverIdPtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId;
|
---|
1652 | OpenDriverAgentHandle = NetworkInterface->OpenDriverAgentHandle;
|
---|
1653 | OpenDriverControllerHandle = NetworkInterface->OpenDriverControllerHandle;
|
---|
1654 | HandleOfProtocolInterfacePtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle;
|
---|
1655 | Interface = &NetworkInterface->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
|
---|
1656 | NewNetworkInterfaceInstalled = TRUE;
|
---|
1657 | if (IsNew) {
|
---|
1658 | InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NetworkInterface->Entry);
|
---|
1659 | mNumNetworkInterface++;
|
---|
1660 | }
|
---|
1661 |
|
---|
1662 | gBS->RestoreTPL (OldTpl);
|
---|
1663 | } else {
|
---|
1664 | // Record REST_EX instance. REST_EX is created when client asks for Redfish service discovery.
|
---|
1665 | // Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
|
---|
1666 | // when discovery.
|
---|
1667 |
|
---|
1668 | RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL));
|
---|
1669 | if (RestExInstance == NULL) {
|
---|
1670 | return EFI_OUT_OF_RESOURCES;
|
---|
1671 | }
|
---|
1672 |
|
---|
1673 | RestExInstance->OpenDriverAgentHandle = This->DriverBindingHandle;
|
---|
1674 | RestExInstance->OpenDriverControllerHandle = ControllerHandle;
|
---|
1675 | RestExInstance->RestExControllerHandle = ControllerHandle;
|
---|
1676 | InitializeListHead (&RestExInstance->Entry);
|
---|
1677 | InsertTailList (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
|
---|
1678 | mNumRestExInstance++;
|
---|
1679 | ProtocolDiscoverIdPtr = &RestExInstance->RestExId;
|
---|
1680 | OpenDriverAgentHandle = RestExInstance->OpenDriverAgentHandle;
|
---|
1681 | OpenDriverControllerHandle = RestExInstance->OpenDriverControllerHandle;
|
---|
1682 | HandleOfProtocolInterfacePtr = &RestExInstance->RestExChildHandle;
|
---|
1683 | Interface = (VOID **)&RestExInstance->RestExProtocolInterface;
|
---|
1684 | }
|
---|
1685 |
|
---|
1686 | Status = gBS->InstallProtocolInterface (
|
---|
1687 | &ControllerHandle,
|
---|
1688 | gRequiredProtocol[Index].DiscoveredProtocolGuid,
|
---|
1689 | EFI_NATIVE_INTERFACE,
|
---|
1690 | ProtocolDiscoverIdPtr
|
---|
1691 | );
|
---|
1692 | if (EFI_ERROR (Status)) {
|
---|
1693 | Index++;
|
---|
1694 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
|
---|
1695 | break;
|
---|
1696 | }
|
---|
1697 |
|
---|
1698 | continue;
|
---|
1699 | }
|
---|
1700 |
|
---|
1701 | //
|
---|
1702 | // Create service binding child and open it BY_DRIVER.
|
---|
1703 | //
|
---|
1704 | Status = NetLibCreateServiceChild (
|
---|
1705 | ControllerHandle,
|
---|
1706 | This->ImageHandle,
|
---|
1707 | gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
|
---|
1708 | HandleOfProtocolInterfacePtr
|
---|
1709 | );
|
---|
1710 | if (!EFI_ERROR (Status)) {
|
---|
1711 | Status = gBS->OpenProtocol (
|
---|
1712 | *HandleOfProtocolInterfacePtr,
|
---|
1713 | gRequiredProtocol[Index].RequiredProtocolGuid,
|
---|
1714 | Interface,
|
---|
1715 | OpenDriverAgentHandle,
|
---|
1716 | OpenDriverControllerHandle,
|
---|
1717 | EFI_OPEN_PROTOCOL_BY_DRIVER
|
---|
1718 | );
|
---|
1719 | if (!EFI_ERROR (Status)) {
|
---|
1720 | if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {
|
---|
1721 | // Install Redfish Discover Protocol when EFI REST EX protocol is discovered.
|
---|
1722 | // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
|
---|
1723 | // acquires Redfish service over network interface.
|
---|
1724 |
|
---|
1725 | if (!NewNetworkInterfaceInstalled) {
|
---|
1726 | NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);
|
---|
1727 | if (NetworkInterface == NULL) {
|
---|
1728 | DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __func__));
|
---|
1729 | return Status;
|
---|
1730 | }
|
---|
1731 | }
|
---|
1732 |
|
---|
1733 | NewNetworkInterfaceInstalled = FALSE;
|
---|
1734 | NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;
|
---|
1735 |
|
---|
1736 | RestExInstance->Signature = EFI_REDFISH_DISCOVER_DATA_SIGNATURE;
|
---|
1737 |
|
---|
1738 | RestExInstance->RedfishDiscoverProtocol.GetNetworkInterfaceList = RedfishServiceGetNetworkInterface;
|
---|
1739 | RestExInstance->RedfishDiscoverProtocol.AcquireRedfishService = RedfishServiceAcquireService;
|
---|
1740 | RestExInstance->RedfishDiscoverProtocol.AbortAcquireRedfishService = RedfishServiceAbortAcquire;
|
---|
1741 | RestExInstance->RedfishDiscoverProtocol.ReleaseRedfishService = RedfishServiceReleaseService;
|
---|
1742 |
|
---|
1743 | Status = gBS->InstallProtocolInterface (
|
---|
1744 | &NetworkInterface->EfiRedfishDiscoverProtocolHandle,
|
---|
1745 | &gEfiRedfishDiscoverProtocolGuid,
|
---|
1746 | EFI_NATIVE_INTERFACE,
|
---|
1747 | (VOID *)&RestExInstance->RedfishDiscoverProtocol
|
---|
1748 | );
|
---|
1749 | if (EFI_ERROR (Status)) {
|
---|
1750 | DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __func__));
|
---|
1751 | }
|
---|
1752 | } else {
|
---|
1753 | DEBUG ((DEBUG_MANAGEABILITY, "%a: Not REST EX, continue with next\n", __func__));
|
---|
1754 | Index++;
|
---|
1755 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
|
---|
1756 | break;
|
---|
1757 | }
|
---|
1758 |
|
---|
1759 | continue;
|
---|
1760 | }
|
---|
1761 | }
|
---|
1762 |
|
---|
1763 | return Status;
|
---|
1764 | } else {
|
---|
1765 | Index++;
|
---|
1766 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
|
---|
1767 | break;
|
---|
1768 | }
|
---|
1769 |
|
---|
1770 | continue;
|
---|
1771 | }
|
---|
1772 | } while (Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)));
|
---|
1773 |
|
---|
1774 | return EFI_DEVICE_ERROR;
|
---|
1775 | }
|
---|
1776 |
|
---|
1777 | /**
|
---|
1778 | Close the protocol opened for Redfish discovery. This function also destroy
|
---|
1779 | the network services.
|
---|
1780 |
|
---|
1781 | @param[in] ThisBindingProtocol A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
1782 | @param[in] ControllerHandle The handle of the controller to test. This handle
|
---|
1783 | must support a protocol interface that supplies
|
---|
1784 | an I/O abstraction to the driver.
|
---|
1785 | @param[in] ThisRequiredProtocol Pointer to the instance of REDFISH_DISCOVER_REQUIRED_PROTOCOL.
|
---|
1786 | @param[in] DriverAgentHandle Driver agent handle which used to open protocol earlier.
|
---|
1787 | @param[in] DriverControllerHandle Driver controller handle which used to open protocol earlier.
|
---|
1788 |
|
---|
1789 | @retval EFI_SUCCESS Protocol is closed successfully.
|
---|
1790 | @retval Others Protocol is closed unsuccessfully.
|
---|
1791 |
|
---|
1792 | **/
|
---|
1793 | EFI_STATUS
|
---|
1794 | CloseProtocolService (
|
---|
1795 | IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,
|
---|
1796 | IN EFI_HANDLE ControllerHandle,
|
---|
1797 | IN REDFISH_DISCOVER_REQUIRED_PROTOCOL *ThisRequiredProtocol,
|
---|
1798 | IN EFI_HANDLE DriverAgentHandle,
|
---|
1799 | IN EFI_HANDLE DriverControllerHandle
|
---|
1800 | )
|
---|
1801 | {
|
---|
1802 | EFI_STATUS Status;
|
---|
1803 |
|
---|
1804 | Status = gBS->CloseProtocol (
|
---|
1805 | ControllerHandle,
|
---|
1806 | ThisRequiredProtocol->RequiredProtocolGuid,
|
---|
1807 | DriverAgentHandle,
|
---|
1808 | DriverControllerHandle
|
---|
1809 | );
|
---|
1810 | if (!EFI_ERROR (Status)) {
|
---|
1811 | NetLibDestroyServiceChild (
|
---|
1812 | ControllerHandle,
|
---|
1813 | ThisBindingProtocol->ImageHandle,
|
---|
1814 | ThisRequiredProtocol->RequiredServiceBindingProtocolGuid,
|
---|
1815 | ControllerHandle
|
---|
1816 | );
|
---|
1817 | }
|
---|
1818 |
|
---|
1819 | return Status;
|
---|
1820 | }
|
---|
1821 |
|
---|
1822 | /**
|
---|
1823 | Stop the services on network interface.
|
---|
1824 |
|
---|
1825 | @param[in] ThisBindingProtocol A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
1826 | @param[in] ControllerHandle The handle of the controller to test. This handle
|
---|
1827 | must support a protocol interface that supplies
|
---|
1828 | an I/O abstraction to the driver.
|
---|
1829 | @retval EFI_SUCCESS One of required protocol is found.
|
---|
1830 | @retval Others Failed to stop the services on network interface.
|
---|
1831 | **/
|
---|
1832 | EFI_STATUS
|
---|
1833 | StopServiceOnNetworkInterface (
|
---|
1834 | IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,
|
---|
1835 | IN EFI_HANDLE ControllerHandle
|
---|
1836 | )
|
---|
1837 | {
|
---|
1838 | UINT32 Index;
|
---|
1839 | EFI_STATUS Status;
|
---|
1840 | VOID *Interface;
|
---|
1841 | EFI_TPL OldTpl;
|
---|
1842 | EFI_HANDLE DiscoverProtocolHandle;
|
---|
1843 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
1844 | EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
|
---|
1845 | EFI_REDFISH_DISCOVER_PROTOCOL *RedfishDiscoverProtocol;
|
---|
1846 |
|
---|
1847 | for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {
|
---|
1848 | Status = gBS->HandleProtocol (
|
---|
1849 | ControllerHandle,
|
---|
1850 | gRequiredProtocol[Index].RequiredProtocolGuid,
|
---|
1851 | (VOID **)&Interface
|
---|
1852 | );
|
---|
1853 | if (!EFI_ERROR (Status)) {
|
---|
1854 | if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
|
---|
1855 | if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
|
---|
1856 | return EFI_NOT_FOUND;
|
---|
1857 | }
|
---|
1858 |
|
---|
1859 | OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
|
---|
1860 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
1861 | while (TRUE) {
|
---|
1862 | if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) {
|
---|
1863 | DiscoverProtocolHandle = ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;
|
---|
1864 | //
|
---|
1865 | // Close protocol and destroy service.
|
---|
1866 | //
|
---|
1867 | Status = CloseProtocolService (
|
---|
1868 | ThisBindingProtocol,
|
---|
1869 | ControllerHandle,
|
---|
1870 | &gRequiredProtocol[Index],
|
---|
1871 | ThisNetworkInterface->OpenDriverAgentHandle,
|
---|
1872 | ThisNetworkInterface->OpenDriverControllerHandle
|
---|
1873 | );
|
---|
1874 | if (!EFI_ERROR (Status)) {
|
---|
1875 | Status = DestroyRedfishNetworkInterface (ThisNetworkInterface);
|
---|
1876 | }
|
---|
1877 |
|
---|
1878 | gBS->RestoreTPL (OldTpl);
|
---|
1879 |
|
---|
1880 | //
|
---|
1881 | // Disconnect EFI Redfish discover driver controller to notify the
|
---|
1882 | // client which uses .EFI Redfish discover protocol.
|
---|
1883 | //
|
---|
1884 | if (DiscoverProtocolHandle != NULL) {
|
---|
1885 | Status = gBS->HandleProtocol (
|
---|
1886 | DiscoverProtocolHandle,
|
---|
1887 | &gEfiRedfishDiscoverProtocolGuid,
|
---|
1888 | (VOID **)&RedfishDiscoverProtocol
|
---|
1889 | );
|
---|
1890 | if (!EFI_ERROR (Status)) {
|
---|
1891 | RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (RedfishDiscoverProtocol);
|
---|
1892 | //
|
---|
1893 | // Stop Redfish service discovery.
|
---|
1894 | //
|
---|
1895 | RedfishDiscoverProtocol->AbortAcquireRedfishService (
|
---|
1896 | RedfishDiscoverProtocol,
|
---|
1897 | RestExInstance->NetworkInterfaceInstances
|
---|
1898 | );
|
---|
1899 |
|
---|
1900 | gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
|
---|
1901 | Status = gBS->UninstallProtocolInterface (
|
---|
1902 | DiscoverProtocolHandle,
|
---|
1903 | &gEfiRedfishDiscoverProtocolGuid,
|
---|
1904 | (VOID *)&RestExInstance->RedfishDiscoverProtocol
|
---|
1905 | );
|
---|
1906 | }
|
---|
1907 | }
|
---|
1908 |
|
---|
1909 | return Status;
|
---|
1910 | }
|
---|
1911 |
|
---|
1912 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
|
---|
1913 | break;
|
---|
1914 | }
|
---|
1915 |
|
---|
1916 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
|
---|
1917 | }
|
---|
1918 |
|
---|
1919 | gBS->RestoreTPL (OldTpl);
|
---|
1920 | } else {
|
---|
1921 | if (IsListEmpty (&mEfiRedfishDiscoverRestExInstance)) {
|
---|
1922 | return EFI_NOT_FOUND;
|
---|
1923 | }
|
---|
1924 |
|
---|
1925 | OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
|
---|
1926 | RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverRestExInstance);
|
---|
1927 | while (TRUE) {
|
---|
1928 | if (RestExInstance->RestExChildHandle == ControllerHandle) {
|
---|
1929 | Status = CloseProtocolService (
|
---|
1930 | // Close REST_EX protocol.
|
---|
1931 | ThisBindingProtocol,
|
---|
1932 | ControllerHandle,
|
---|
1933 | &gRequiredProtocol[Index],
|
---|
1934 | RestExInstance->OpenDriverAgentHandle,
|
---|
1935 | RestExInstance->OpenDriverControllerHandle
|
---|
1936 | );
|
---|
1937 | RemoveEntryList (&RestExInstance->Entry);
|
---|
1938 | FreePool ((VOID *)RestExInstance);
|
---|
1939 | mNumRestExInstance--;
|
---|
1940 | gBS->RestoreTPL (OldTpl);
|
---|
1941 | return Status;
|
---|
1942 | }
|
---|
1943 |
|
---|
1944 | if (IsNodeAtEnd (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry)) {
|
---|
1945 | break;
|
---|
1946 | }
|
---|
1947 |
|
---|
1948 | RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
|
---|
1949 | }
|
---|
1950 |
|
---|
1951 | gBS->RestoreTPL (OldTpl);
|
---|
1952 | }
|
---|
1953 | }
|
---|
1954 | }
|
---|
1955 |
|
---|
1956 | return EFI_NOT_FOUND;
|
---|
1957 | }
|
---|
1958 |
|
---|
1959 | /**
|
---|
1960 | Tests to see if this driver supports a given controller. If a child device is provided,
|
---|
1961 | it further tests to see if this driver supports creating a handle for the specified child device.
|
---|
1962 |
|
---|
1963 | This function checks to see if the driver specified by This supports the device specified by
|
---|
1964 | ControllerHandle. Drivers will typically use the device path attached to
|
---|
1965 | ControllerHandle and/or the services from the bus I/O abstraction attached to
|
---|
1966 | ControllerHandle to determine if the driver supports ControllerHandle. This function
|
---|
1967 | may be called many times during platform initialization. In order to reduce boot times, the tests
|
---|
1968 | performed by this function must be very small, and take as little time as possible to execute. This
|
---|
1969 | function must not change the state of any hardware devices, and this function must be aware that the
|
---|
1970 | device specified by ControllerHandle may already be managed by the same driver or a
|
---|
1971 | different driver. This function must match its calls to AllocatePages() with FreePages(),
|
---|
1972 | AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
---|
1973 | Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
---|
1974 | already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
---|
1975 | to guarantee the state of ControllerHandle is not modified by this function.
|
---|
1976 |
|
---|
1977 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
1978 | @param[in] ControllerHandle The handle of the controller to test. This handle
|
---|
1979 | must support a protocol interface that supplies
|
---|
1980 | an I/O abstraction to the driver.
|
---|
1981 | @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
---|
1982 | parameter is ignored by device drivers, and is optional for bus
|
---|
1983 | drivers. For bus drivers, if this parameter is not NULL, then
|
---|
1984 | the bus driver must determine if the bus controller specified
|
---|
1985 | by ControllerHandle and the child controller specified
|
---|
1986 | by RemainingDevicePath are both supported by this
|
---|
1987 | bus driver.
|
---|
1988 |
|
---|
1989 | @retval EFI_SUCCESS The device specified by ControllerHandle and
|
---|
1990 | RemainingDevicePath is supported by the driver specified by This.
|
---|
1991 | @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
---|
1992 | RemainingDevicePath is already being managed by the driver
|
---|
1993 | specified by This.
|
---|
1994 | @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
---|
1995 | RemainingDevicePath is already being managed by a different
|
---|
1996 | driver or an application that requires exclusive access.
|
---|
1997 | Currently not implemented.
|
---|
1998 | @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
---|
1999 | RemainingDevicePath is not supported by the driver specified by This.
|
---|
2000 | **/
|
---|
2001 | EFI_STATUS
|
---|
2002 | EFIAPI
|
---|
2003 | RedfishDiscoverDriverBindingSupported (
|
---|
2004 | IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
---|
2005 | IN EFI_HANDLE ControllerHandle,
|
---|
2006 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
---|
2007 | )
|
---|
2008 | {
|
---|
2009 | return TestForRequiredProtocols (This, ControllerHandle);
|
---|
2010 | }
|
---|
2011 |
|
---|
2012 | /**
|
---|
2013 | Starts a device controller or a bus controller.
|
---|
2014 |
|
---|
2015 | The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
---|
2016 | As a result, much of the error checking on the parameters to Start() has been moved into this
|
---|
2017 | common boot service. It is legal to call Start() from other locations,
|
---|
2018 | but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
---|
2019 | 1. ControllerHandle must be a valid EFI_HANDLE.
|
---|
2020 | 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
---|
2021 | EFI_DEVICE_PATH_PROTOCOL.
|
---|
2022 | 3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
---|
2023 | have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
---|
2024 |
|
---|
2025 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
2026 | @param[in] ControllerHandle The handle of the controller to start. This handle
|
---|
2027 | must support a protocol interface that supplies
|
---|
2028 | an I/O abstraction to the driver.
|
---|
2029 | @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
---|
2030 | parameter is ignored by device drivers, and is optional for bus
|
---|
2031 | drivers. For a bus driver, if this parameter is NULL, then handles
|
---|
2032 | for all the children of Controller are created by this driver.
|
---|
2033 | If this parameter is not NULL and the first Device Path Node is
|
---|
2034 | not the End of Device Path Node, then only the handle for the
|
---|
2035 | child device specified by the first Device Path Node of
|
---|
2036 | RemainingDevicePath is created by this driver.
|
---|
2037 | If the first Device Path Node of RemainingDevicePath is
|
---|
2038 | the End of Device Path Node, no child handle is created by this
|
---|
2039 | driver.
|
---|
2040 |
|
---|
2041 | @retval EFI_SUCCESS The device was started.
|
---|
2042 | @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
---|
2043 | @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
---|
2044 | @retval Others The driver failed to start the device.
|
---|
2045 |
|
---|
2046 | **/
|
---|
2047 | EFI_STATUS
|
---|
2048 | EFIAPI
|
---|
2049 | RedfishDiscoverDriverBindingStart (
|
---|
2050 | IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
---|
2051 | IN EFI_HANDLE ControllerHandle,
|
---|
2052 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
---|
2053 | )
|
---|
2054 | {
|
---|
2055 | return BuildupNetworkInterface (This, ControllerHandle);
|
---|
2056 | }
|
---|
2057 |
|
---|
2058 | /**
|
---|
2059 | Stops a device controller or a bus controller.
|
---|
2060 |
|
---|
2061 | The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
---|
2062 | As a result, much of the error checking on the parameters to Stop() has been moved
|
---|
2063 | into this common boot service. It is legal to call Stop() from other locations,
|
---|
2064 | but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
---|
2065 | 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
---|
2066 | same driver's Start() function.
|
---|
2067 | 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
---|
2068 | EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
---|
2069 | Start() function, and the Start() function must have called OpenProtocol() on
|
---|
2070 | ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
---|
2071 |
|
---|
2072 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
---|
2073 | @param[in] ControllerHandle A handle to the device being stopped. The handle must
|
---|
2074 | support a bus specific I/O protocol for the driver
|
---|
2075 | to use to stop the device.
|
---|
2076 | @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
---|
2077 | @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
---|
2078 | if NumberOfChildren is 0.
|
---|
2079 |
|
---|
2080 | @retval EFI_SUCCESS The device was stopped.
|
---|
2081 | @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
---|
2082 |
|
---|
2083 | **/
|
---|
2084 | EFI_STATUS
|
---|
2085 | EFIAPI
|
---|
2086 | RedfishDiscoverDriverBindingStop (
|
---|
2087 | IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
---|
2088 | IN EFI_HANDLE ControllerHandle,
|
---|
2089 | IN UINTN NumberOfChildren,
|
---|
2090 | IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
---|
2091 | )
|
---|
2092 | {
|
---|
2093 | return StopServiceOnNetworkInterface (This, ControllerHandle);
|
---|
2094 | }
|
---|
2095 |
|
---|
2096 | EFI_DRIVER_BINDING_PROTOCOL gRedfishDiscoverDriverBinding = {
|
---|
2097 | RedfishDiscoverDriverBindingSupported,
|
---|
2098 | RedfishDiscoverDriverBindingStart,
|
---|
2099 | RedfishDiscoverDriverBindingStop,
|
---|
2100 | REDFISH_DISCOVER_VERSION,
|
---|
2101 | NULL,
|
---|
2102 | NULL
|
---|
2103 | };
|
---|
2104 |
|
---|
2105 | /**
|
---|
2106 | This is the declaration of an EFI image entry point.
|
---|
2107 |
|
---|
2108 | @param ImageHandle The firmware allocated handle for the UEFI image.
|
---|
2109 | @param SystemTable A pointer to the EFI System Table.
|
---|
2110 |
|
---|
2111 | @retval EFI_SUCCESS The operation completed successfully.
|
---|
2112 | @retval Others An unexpected error occurred.
|
---|
2113 | **/
|
---|
2114 | EFI_STATUS
|
---|
2115 | EFIAPI
|
---|
2116 | RedfishDiscoverEntryPoint (
|
---|
2117 | IN EFI_HANDLE ImageHandle,
|
---|
2118 | IN EFI_SYSTEM_TABLE *SystemTable
|
---|
2119 | )
|
---|
2120 | {
|
---|
2121 | EFI_STATUS Status;
|
---|
2122 |
|
---|
2123 | Status = EFI_SUCCESS;
|
---|
2124 | InitializeListHead (&mRedfishDiscoverList);
|
---|
2125 | InitializeListHead (&mRedfishInstanceList);
|
---|
2126 | InitializeListHead (&mEfiRedfishDiscoverNetworkInterface);
|
---|
2127 | InitializeListHead (&mEfiRedfishDiscoverRestExInstance);
|
---|
2128 | //
|
---|
2129 | // Install binding protocol to obtain UDP and REST EX protocol.
|
---|
2130 | //
|
---|
2131 | Status = EfiLibInstallDriverBindingComponentName2 (
|
---|
2132 | ImageHandle,
|
---|
2133 | SystemTable,
|
---|
2134 | &gRedfishDiscoverDriverBinding,
|
---|
2135 | ImageHandle,
|
---|
2136 | &gRedfishDiscoverComponentName,
|
---|
2137 | &gRedfishDiscoverComponentName2
|
---|
2138 | );
|
---|
2139 | return Status;
|
---|
2140 | }
|
---|
2141 |
|
---|
2142 | /**
|
---|
2143 | This is the unload handle for Redfish discover module.
|
---|
2144 |
|
---|
2145 | Disconnect the driver specified by ImageHandle from all the devices in the handle database.
|
---|
2146 | Uninstall all the protocols installed in the driver entry point.
|
---|
2147 |
|
---|
2148 | @param[in] ImageHandle The drivers' driver image.
|
---|
2149 |
|
---|
2150 | @retval EFI_SUCCESS The image is unloaded.
|
---|
2151 | @retval Others Failed to unload the image.
|
---|
2152 |
|
---|
2153 | **/
|
---|
2154 | EFI_STATUS
|
---|
2155 | EFIAPI
|
---|
2156 | RedfishDiscoverUnload (
|
---|
2157 | IN EFI_HANDLE ImageHandle
|
---|
2158 | )
|
---|
2159 | {
|
---|
2160 | EFI_STATUS Status;
|
---|
2161 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
|
---|
2162 |
|
---|
2163 | Status = EFI_SUCCESS;
|
---|
2164 | // Destroy all network interfaces found by EFI Redfish Discover driver and
|
---|
2165 | // stop services created for Redfish Discover.
|
---|
2166 |
|
---|
2167 | while (!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
|
---|
2168 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
|
---|
2169 | StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);
|
---|
2170 | }
|
---|
2171 |
|
---|
2172 | return Status;
|
---|
2173 | }
|
---|