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