]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/Ip4Dxe/Ip4Config2Impl.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / Ip4Dxe / Ip4Config2Impl.c
CommitLineData
1f6729ff 1/** @file\r
2 The implementation of EFI IPv4 Configuration II Protocol.\r
3\r
d1102dba 4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
4f0f2316 5 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
1f6729ff 6\r
9d510e61 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1f6729ff 8\r
9**/\r
10\r
11#include "Ip4Impl.h"\r
12\r
d1050b9d 13LIST_ENTRY mIp4Config2InstanceList = { &mIp4Config2InstanceList, &mIp4Config2InstanceList };\r
1f6729ff 14\r
15/**\r
16 The event process routine when the DHCPv4 service binding protocol is installed\r
17 in the system.\r
18\r
19 @param[in] Event Not used.\r
20 @param[in] Context Pointer to the IP4 config2 instance data.\r
21\r
22**/\r
23VOID\r
24EFIAPI\r
25Ip4Config2OnDhcp4SbInstalled (\r
26 IN EFI_EVENT Event,\r
27 IN VOID *Context\r
28 );\r
29\r
30/**\r
31 Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.\r
32\r
33 @param[in, out] Instance The buffer of IP4 config2 instance to be freed.\r
34\r
35 @retval EFI_SUCCESS The child was successfully destroyed.\r
36 @retval Others Failed to destroy the child.\r
37\r
38**/\r
39EFI_STATUS\r
40Ip4Config2DestroyDhcp4 (\r
41 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
42 )\r
43{\r
d1050b9d
MK
44 IP4_SERVICE *IpSb;\r
45 EFI_STATUS Status;\r
46 EFI_DHCP4_PROTOCOL *Dhcp4;\r
1f6729ff 47\r
48 Dhcp4 = Instance->Dhcp4;\r
49 ASSERT (Dhcp4 != NULL);\r
50\r
51 Dhcp4->Stop (Dhcp4);\r
52 Dhcp4->Configure (Dhcp4, NULL);\r
53 Instance->Dhcp4 = NULL;\r
54\r
55 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
56\r
57 //\r
58 // Close DHCPv4 protocol and destroy the child.\r
59 //\r
60 Status = gBS->CloseProtocol (\r
61 Instance->Dhcp4Handle,\r
62 &gEfiDhcp4ProtocolGuid,\r
63 IpSb->Image,\r
64 IpSb->Controller\r
65 );\r
66 if (EFI_ERROR (Status)) {\r
67 return Status;\r
68 }\r
69\r
70 Status = NetLibDestroyServiceChild (\r
71 IpSb->Controller,\r
72 IpSb->Image,\r
73 &gEfiDhcp4ServiceBindingProtocolGuid,\r
74 Instance->Dhcp4Handle\r
75 );\r
76\r
77 Instance->Dhcp4Handle = NULL;\r
78\r
d1102dba 79 return Status;\r
1f6729ff 80}\r
81\r
1f6729ff 82/**\r
83 Update the current policy to NewPolicy. During the transition\r
84 period, the default router list\r
85 and address list in all interfaces will be released.\r
86\r
87 @param[in] IpSb The IP4 service binding instance.\r
88 @param[in] NewPolicy The new policy to be updated to.\r
89\r
90**/\r
91VOID\r
92Ip4Config2OnPolicyChanged (\r
d1050b9d
MK
93 IN IP4_SERVICE *IpSb,\r
94 IN EFI_IP4_CONFIG2_POLICY NewPolicy\r
1f6729ff 95 )\r
96{\r
d1050b9d
MK
97 IP4_INTERFACE *IpIf;\r
98 IP4_ROUTE_TABLE *RouteTable;\r
1f6729ff 99\r
100 //\r
101 // Currently there are only two policies: static and dhcp. Regardless of\r
102 // what transition is going on, i.e., static -> dhcp and dhcp ->\r
103 // static, we have to free default router table and all addresses.\r
104 //\r
105\r
106 if (IpSb->DefaultInterface != NULL) {\r
107 if (IpSb->DefaultRouteTable != NULL) {\r
108 Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
d1102dba 109 IpSb->DefaultRouteTable = NULL;\r
1f6729ff 110 }\r
111\r
112 Ip4CancelReceive (IpSb->DefaultInterface);\r
113\r
114 Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
115 IpSb->DefaultInterface = NULL;\r
116 }\r
117\r
118 Ip4CleanAssembleTable (&IpSb->Assemble);\r
119\r
120 //\r
121 // Create new default interface and route table.\r
d1102dba 122 //\r
1f6729ff 123 IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
124 if (IpIf == NULL) {\r
d1050b9d 125 return;\r
1f6729ff 126 }\r
127\r
128 RouteTable = Ip4CreateRouteTable ();\r
129 if (RouteTable == NULL) {\r
130 Ip4FreeInterface (IpIf, NULL);\r
d1050b9d 131 return;\r
1f6729ff 132 }\r
d1102dba 133\r
d1050b9d 134 IpSb->DefaultInterface = IpIf;\r
1f6729ff 135 InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
136 IpSb->DefaultRouteTable = RouteTable;\r
137 Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
138\r
d1050b9d 139 if ((IpSb->State == IP4_SERVICE_CONFIGED) || (IpSb->State == IP4_SERVICE_STARTED)) {\r
1f6729ff 140 IpSb->State = IP4_SERVICE_UNSTARTED;\r
141 }\r
142\r
143 //\r
144 // Start the dhcp configuration.\r
145 //\r
146 if (NewPolicy == Ip4Config2PolicyDhcp) {\r
147 Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
148 }\r
1f6729ff 149}\r
150\r
151/**\r
152 Signal the registered event. It is the callback routine for NetMapIterate.\r
153\r
154 @param[in] Map Points to the list of registered event.\r
155 @param[in] Item The registered event.\r
156 @param[in] Arg Not used.\r
157\r
158 @retval EFI_SUCCESS The event was signaled successfully.\r
159**/\r
160EFI_STATUS\r
161EFIAPI\r
162Ip4Config2SignalEvent (\r
d1050b9d
MK
163 IN NET_MAP *Map,\r
164 IN NET_MAP_ITEM *Item,\r
165 IN VOID *Arg\r
1f6729ff 166 )\r
167{\r
d1050b9d 168 gBS->SignalEvent ((EFI_EVENT)Item->Key);\r
1f6729ff 169\r
170 return EFI_SUCCESS;\r
171}\r
172\r
173/**\r
174 Read the configuration data from variable storage according to the VarName and\r
175 gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the\r
6c585b52 176 data is corrupted, it clears the variable data to ZERO. Otherwise, it outputs the\r
1f6729ff 177 configuration data to IP4_CONFIG2_INSTANCE.\r
178\r
179 @param[in] VarName The pointer to the variable name\r
180 @param[in, out] Instance The pointer to the IP4 config2 instance data.\r
181\r
182 @retval EFI_NOT_FOUND The variable can not be found or already corrupted.\r
183 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.\r
184 @retval EFI_SUCCESS The configuration data was retrieved successfully.\r
185\r
186**/\r
187EFI_STATUS\r
188Ip4Config2ReadConfigData (\r
d1050b9d
MK
189 IN CHAR16 *VarName,\r
190 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 191 )\r
192{\r
d1050b9d
MK
193 EFI_STATUS Status;\r
194 UINTN VarSize;\r
195 IP4_CONFIG2_VARIABLE *Variable;\r
196 IP4_CONFIG2_DATA_ITEM *DataItem;\r
197 UINTN Index;\r
198 IP4_CONFIG2_DATA_RECORD DataRecord;\r
199 CHAR8 *Data;\r
1f6729ff 200\r
201 //\r
202 // Try to read the configuration variable.\r
203 //\r
204 VarSize = 0;\r
205 Status = gRT->GetVariable (\r
206 VarName,\r
207 &gEfiIp4Config2ProtocolGuid,\r
208 NULL,\r
209 &VarSize,\r
210 NULL\r
211 );\r
212\r
213 if (Status == EFI_BUFFER_TOO_SMALL) {\r
214 //\r
215 // Allocate buffer and read the config variable.\r
216 //\r
217 Variable = AllocatePool (VarSize);\r
218 if (Variable == NULL) {\r
219 return EFI_OUT_OF_RESOURCES;\r
220 }\r
221\r
222 Status = gRT->GetVariable (\r
223 VarName,\r
224 &gEfiIp4Config2ProtocolGuid,\r
225 NULL,\r
226 &VarSize,\r
227 Variable\r
228 );\r
d1050b9d 229 if (EFI_ERROR (Status) || ((UINT16)(~NetblockChecksum ((UINT8 *)Variable, (UINT32)VarSize)) != 0)) {\r
1f6729ff 230 //\r
231 // GetVariable still error or the variable is corrupted.\r
232 // Fall back to the default value.\r
233 //\r
234 FreePool (Variable);\r
235\r
236 //\r
237 // Remove the problematic variable and return EFI_NOT_FOUND, a new\r
238 // variable will be set again.\r
239 //\r
240 gRT->SetVariable (\r
241 VarName,\r
242 &gEfiIp4Config2ProtocolGuid,\r
243 IP4_CONFIG2_VARIABLE_ATTRIBUTE,\r
244 0,\r
245 NULL\r
246 );\r
247\r
248 return EFI_NOT_FOUND;\r
249 }\r
250\r
1f6729ff 251 for (Index = 0; Index < Variable->DataRecordCount; Index++) {\r
1f6729ff 252 CopyMem (&DataRecord, &Variable->DataRecord[Index], sizeof (DataRecord));\r
253\r
254 DataItem = &Instance->DataItem[DataRecord.DataType];\r
255 if (DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED) &&\r
256 (DataItem->DataSize != DataRecord.DataSize)\r
d1050b9d
MK
257 )\r
258 {\r
1f6729ff 259 //\r
260 // Perhaps a corrupted data record...\r
261 //\r
262 continue;\r
263 }\r
264\r
265 if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) {\r
266 //\r
267 // This data item has variable length data.\r
268 //\r
269 DataItem->Data.Ptr = AllocatePool (DataRecord.DataSize);\r
270 if (DataItem->Data.Ptr == NULL) {\r
271 //\r
272 // no memory resource\r
273 //\r
274 continue;\r
275 }\r
276 }\r
277\r
d1050b9d 278 Data = (CHAR8 *)Variable + DataRecord.Offset;\r
1f6729ff 279 CopyMem (DataItem->Data.Ptr, Data, DataRecord.DataSize);\r
280\r
281 DataItem->DataSize = DataRecord.DataSize;\r
282 DataItem->Status = EFI_SUCCESS;\r
283 }\r
284\r
285 FreePool (Variable);\r
286 return EFI_SUCCESS;\r
287 }\r
288\r
289 return Status;\r
290}\r
291\r
292/**\r
293 Write the configuration data from IP4_CONFIG2_INSTANCE to variable storage.\r
294\r
295 @param[in] VarName The pointer to the variable name.\r
296 @param[in] Instance The pointer to the IP4 config2 instance data.\r
297\r
298 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.\r
299 @retval EFI_SUCCESS The configuration data is written successfully.\r
300\r
301**/\r
302EFI_STATUS\r
303Ip4Config2WriteConfigData (\r
d1050b9d
MK
304 IN CHAR16 *VarName,\r
305 IN IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 306 )\r
307{\r
d1050b9d
MK
308 UINTN Index;\r
309 UINTN VarSize;\r
310 IP4_CONFIG2_DATA_ITEM *DataItem;\r
311 IP4_CONFIG2_VARIABLE *Variable;\r
312 IP4_CONFIG2_DATA_RECORD *DataRecord;\r
313 CHAR8 *Heap;\r
314 EFI_STATUS Status;\r
1f6729ff 315\r
316 VarSize = sizeof (IP4_CONFIG2_VARIABLE) - sizeof (IP4_CONFIG2_DATA_RECORD);\r
317\r
318 for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {\r
1f6729ff 319 DataItem = &Instance->DataItem[Index];\r
320 if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) {\r
1f6729ff 321 VarSize += sizeof (IP4_CONFIG2_DATA_RECORD) + DataItem->DataSize;\r
322 }\r
323 }\r
324\r
325 Variable = AllocatePool (VarSize);\r
326 if (Variable == NULL) {\r
327 return EFI_OUT_OF_RESOURCES;\r
328 }\r
329\r
d1050b9d 330 Heap = (CHAR8 *)Variable + VarSize;\r
1f6729ff 331 Variable->DataRecordCount = 0;\r
332\r
333 for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {\r
1f6729ff 334 DataItem = &Instance->DataItem[Index];\r
335 if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) {\r
1f6729ff 336 Heap -= DataItem->DataSize;\r
337 CopyMem (Heap, DataItem->Data.Ptr, DataItem->DataSize);\r
338\r
339 DataRecord = &Variable->DataRecord[Variable->DataRecordCount];\r
d1050b9d
MK
340 DataRecord->DataType = (EFI_IP4_CONFIG2_DATA_TYPE)Index;\r
341 DataRecord->DataSize = (UINT32)DataItem->DataSize;\r
342 DataRecord->Offset = (UINT16)(Heap - (CHAR8 *)Variable);\r
1f6729ff 343\r
344 Variable->DataRecordCount++;\r
345 }\r
346 }\r
347\r
348 Variable->Checksum = 0;\r
d1050b9d 349 Variable->Checksum = (UINT16) ~NetblockChecksum ((UINT8 *)Variable, (UINT32)VarSize);\r
1f6729ff 350\r
351 Status = gRT->SetVariable (\r
352 VarName,\r
353 &gEfiIp4Config2ProtocolGuid,\r
354 IP4_CONFIG2_VARIABLE_ATTRIBUTE,\r
355 VarSize,\r
356 Variable\r
357 );\r
358\r
359 FreePool (Variable);\r
360\r
361 return Status;\r
362}\r
363\r
1f6729ff 364/**\r
d1102dba
LG
365 Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData.\r
366 The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the\r
1f6729ff 367 IP4 driver.\r
368\r
369 @param[in] IpSb The IP4 service binding instance.\r
370 @param[out] Table The built IP4 route table.\r
371\r
372 @retval EFI_SUCCESS The route table is successfully build\r
6c585b52 373 @retval EFI_NOT_FOUND Failed to allocate the memory for the route table.\r
1f6729ff 374\r
375**/\r
376EFI_STATUS\r
377Ip4Config2BuildDefaultRouteTable (\r
d1050b9d
MK
378 IN IP4_SERVICE *IpSb,\r
379 OUT EFI_IP4_ROUTE_TABLE *Table\r
1f6729ff 380 )\r
381{\r
d1050b9d
MK
382 LIST_ENTRY *Entry;\r
383 IP4_ROUTE_ENTRY *RtEntry;\r
384 UINT32 Count;\r
385 INT32 Index;\r
1f6729ff 386\r
387 if (IpSb->DefaultRouteTable == NULL) {\r
388 return EFI_NOT_FOUND;\r
389 }\r
390\r
391 Count = IpSb->DefaultRouteTable->TotalNum;\r
392\r
393 if (Count == 0) {\r
394 return EFI_NOT_FOUND;\r
395 }\r
396\r
397 //\r
398 // Copy the route entry to EFI route table. Keep the order of\r
399 // route entry copied from most specific to default route. That\r
400 // is, interlevel the route entry from the instance's route area\r
401 // and those from the default route table's route area.\r
402 //\r
403 Count = 0;\r
404\r
364f4efa 405 for (Index = IP4_MASK_MAX; Index >= 0; Index--) {\r
1f6729ff 406 NET_LIST_FOR_EACH (Entry, &(IpSb->DefaultRouteTable->RouteArea[Index])) {\r
407 RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);\r
408\r
409 EFI_IP4 (Table[Count].SubnetAddress) = HTONL (RtEntry->Dest & RtEntry->Netmask);\r
410 EFI_IP4 (Table[Count].SubnetMask) = HTONL (RtEntry->Netmask);\r
411 EFI_IP4 (Table[Count].GatewayAddress) = HTONL (RtEntry->NextHop);\r
412\r
413 Count++;\r
414 }\r
1f6729ff 415 }\r
416\r
417 return EFI_SUCCESS;\r
418}\r
419\r
420/**\r
421 The event process routine when the DHCPv4 service binding protocol is installed\r
422 in the system.\r
423\r
424 @param[in] Event Not used.\r
425 @param[in] Context The pointer to the IP4 config2 instance data.\r
426\r
427**/\r
428VOID\r
429EFIAPI\r
430Ip4Config2OnDhcp4SbInstalled (\r
431 IN EFI_EVENT Event,\r
432 IN VOID *Context\r
433 )\r
434{\r
435 IP4_CONFIG2_INSTANCE *Instance;\r
436\r
d1050b9d 437 Instance = (IP4_CONFIG2_INSTANCE *)Context;\r
1f6729ff 438\r
439 if ((Instance->Dhcp4Handle != NULL) || (Instance->Policy != Ip4Config2PolicyDhcp)) {\r
440 //\r
441 // The DHCP4 child is already created or the policy is no longer DHCP.\r
442 //\r
d1050b9d 443 return;\r
1f6729ff 444 }\r
445\r
446 Ip4StartAutoConfig (Instance);\r
447}\r
448\r
449/**\r
450 Set the station address and subnetmask for the default interface.\r
451\r
e371cc14 452 @param[in] IpSb The pointer to the IP4 service binding instance.\r
1f6729ff 453 @param[in] StationAddress Ip address to be set.\r
454 @param[in] SubnetMask Subnet to be set.\r
455\r
d1102dba
LG
456 @retval EFI_SUCCESS Set default address successful.\r
457 @retval Others Some errors occur in setting.\r
1f6729ff 458\r
459**/\r
460EFI_STATUS\r
461Ip4Config2SetDefaultAddr (\r
d1050b9d
MK
462 IN IP4_SERVICE *IpSb,\r
463 IN IP4_ADDR StationAddress,\r
464 IN IP4_ADDR SubnetMask\r
1f6729ff 465 )\r
466{\r
d1050b9d
MK
467 EFI_STATUS Status;\r
468 IP4_INTERFACE *IpIf;\r
469 IP4_PROTOCOL *Ip4Instance;\r
470 EFI_ARP_PROTOCOL *Arp;\r
471 LIST_ENTRY *Entry;\r
472 IP4_ADDR Subnet;\r
473 IP4_ROUTE_TABLE *RouteTable;\r
1f6729ff 474\r
1f6729ff 475 IpIf = IpSb->DefaultInterface;\r
476 ASSERT (IpIf != NULL);\r
477\r
478 if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {\r
2c320007 479 IpSb->State = IP4_SERVICE_CONFIGED;\r
1f6729ff 480 return EFI_SUCCESS;\r
481 }\r
482\r
e371cc14
JW
483 if (IpSb->Reconfig) {\r
484 //\r
485 // The default address is changed, free the previous interface first.\r
486 //\r
487 if (IpSb->DefaultRouteTable != NULL) {\r
488 Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
d1102dba 489 IpSb->DefaultRouteTable = NULL;\r
e371cc14 490 }\r
1f6729ff 491\r
e371cc14
JW
492 Ip4CancelReceive (IpSb->DefaultInterface);\r
493 Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
494 IpSb->DefaultInterface = NULL;\r
495 //\r
496 // Create new default interface and route table.\r
d1102dba 497 //\r
e371cc14
JW
498 IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
499 if (IpIf == NULL) {\r
500 return EFI_OUT_OF_RESOURCES;\r
501 }\r
1f6729ff 502\r
e371cc14
JW
503 RouteTable = Ip4CreateRouteTable ();\r
504 if (RouteTable == NULL) {\r
505 Ip4FreeInterface (IpIf, NULL);\r
506 return EFI_OUT_OF_RESOURCES;\r
507 }\r
d1102dba 508\r
d1050b9d 509 IpSb->DefaultInterface = IpIf;\r
e371cc14
JW
510 InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
511 IpSb->DefaultRouteTable = RouteTable;\r
512 Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
1f6729ff 513 }\r
1f6729ff 514\r
515 if (IpSb->State == IP4_SERVICE_CONFIGED) {\r
516 IpSb->State = IP4_SERVICE_UNSTARTED;\r
517 }\r
518\r
519 Status = Ip4SetAddress (IpIf, StationAddress, SubnetMask);\r
520 if (EFI_ERROR (Status)) {\r
521 return Status;\r
522 }\r
523\r
524 if (IpIf->Arp != NULL) {\r
d1102dba
LG
525 //\r
526 // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address,\r
1f6729ff 527 // but some IP children may have referenced the default interface before it is configured,\r
528 // these IP instances also consume this ARP protocol so they need to open it BY_CHILD_CONTROLLER.\r
529 //\r
530 Arp = NULL;\r
531 NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {\r
532 Ip4Instance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, AddrLink, IP4_PROTOCOL_SIGNATURE);\r
d1050b9d
MK
533 Status = gBS->OpenProtocol (\r
534 IpIf->ArpHandle,\r
535 &gEfiArpProtocolGuid,\r
536 (VOID **)&Arp,\r
537 gIp4DriverBinding.DriverBindingHandle,\r
538 Ip4Instance->Handle,\r
539 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
540 );\r
1f6729ff 541 if (EFI_ERROR (Status)) {\r
542 return Status;\r
543 }\r
544 }\r
545 }\r
546\r
1f6729ff 547 //\r
548 // Add a route for the connected network.\r
549 //\r
550 Subnet = StationAddress & SubnetMask;\r
551\r
552 Ip4AddRoute (\r
553 IpSb->DefaultRouteTable,\r
554 Subnet,\r
555 SubnetMask,\r
556 IP4_ALLZERO_ADDRESS\r
557 );\r
558\r
d1050b9d 559 IpSb->State = IP4_SERVICE_CONFIGED;\r
e371cc14 560 IpSb->Reconfig = FALSE;\r
d1102dba 561\r
1f6729ff 562 return EFI_SUCCESS;\r
563}\r
564\r
565/**\r
566 Set the station address, subnetmask and gateway address for the default interface.\r
567\r
d1102dba 568 @param[in] Instance The pointer to the IP4 config2 instance data.\r
1f6729ff 569 @param[in] StationAddress Ip address to be set.\r
570 @param[in] SubnetMask Subnet to be set.\r
571 @param[in] GatewayAddress Gateway to be set.\r
572\r
d1102dba
LG
573 @retval EFI_SUCCESS Set default If successful.\r
574 @retval Others Errors occur as indicated.\r
1f6729ff 575\r
576**/\r
577EFI_STATUS\r
578Ip4Config2SetDefaultIf (\r
d1050b9d
MK
579 IN IP4_CONFIG2_INSTANCE *Instance,\r
580 IN IP4_ADDR StationAddress,\r
581 IN IP4_ADDR SubnetMask,\r
582 IN IP4_ADDR GatewayAddress\r
1f6729ff 583 )\r
584{\r
d1050b9d
MK
585 EFI_STATUS Status;\r
586 IP4_SERVICE *IpSb;\r
1f6729ff 587\r
e371cc14
JW
588 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
589\r
f1222593
JW
590 //\r
591 // Check whether the StationAddress/SubnetMask pair is valid.\r
592 //\r
593 if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {\r
594 return EFI_INVALID_PARAMETER;\r
595 }\r
596\r
e371cc14 597 Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
1f6729ff 598 if (EFI_ERROR (Status)) {\r
599 return Status;\r
600 }\r
601\r
602 //\r
603 // Create a route if there is a default router.\r
604 //\r
1f6729ff 605 if (GatewayAddress != IP4_ALLZERO_ADDRESS) {\r
606 Ip4AddRoute (\r
607 IpSb->DefaultRouteTable,\r
608 IP4_ALLZERO_ADDRESS,\r
609 IP4_ALLZERO_ADDRESS,\r
610 GatewayAddress\r
d1102dba 611 );\r
1f6729ff 612 }\r
613\r
614 return EFI_SUCCESS;\r
615}\r
616\r
1f6729ff 617/**\r
618 Release all the DHCP related resources.\r
619\r
620 @param Instance The IP4 config2 instance.\r
621\r
622 @return None\r
623\r
624**/\r
625VOID\r
626Ip4Config2CleanDhcp4 (\r
d1050b9d 627 IN IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 628 )\r
629{\r
d1050b9d 630 IP4_SERVICE *IpSb;\r
1f6729ff 631\r
632 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
633\r
634 if (Instance->Dhcp4 != NULL) {\r
635 Instance->Dhcp4->Stop (Instance->Dhcp4);\r
636\r
637 gBS->CloseProtocol (\r
d1050b9d
MK
638 Instance->Dhcp4Handle,\r
639 &gEfiDhcp4ProtocolGuid,\r
640 IpSb->Image,\r
641 IpSb->Controller\r
642 );\r
1f6729ff 643\r
644 Instance->Dhcp4 = NULL;\r
645 }\r
646\r
647 if (Instance->Dhcp4Handle != NULL) {\r
648 NetLibDestroyServiceChild (\r
649 IpSb->Controller,\r
650 IpSb->Image,\r
651 &gEfiDhcp4ServiceBindingProtocolGuid,\r
652 Instance->Dhcp4Handle\r
653 );\r
654\r
655 Instance->Dhcp4Handle = NULL;\r
656 }\r
657\r
658 if (Instance->Dhcp4Event != NULL) {\r
659 gBS->CloseEvent (Instance->Dhcp4Event);\r
660 Instance->Dhcp4Event = NULL;\r
661 }\r
662}\r
663\r
9feefde0
SEHM
664/**\r
665 This worker function sets the DNS server list for the EFI IPv4 network\r
666 stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL\r
d1102dba 667 manages. The DNS server addresses must be unicast IPv4 addresses.\r
9feefde0
SEHM
668\r
669 @param[in] Instance The pointer to the IP4 config2 instance data.\r
670 @param[in] DataSize The size of the buffer pointed to by Data in bytes.\r
671 @param[in] Data The data buffer to set, points to an array of\r
672 EFI_IPv4_ADDRESS instances.\r
673\r
674 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.\r
675 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.\r
676 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.\r
677 @retval EFI_ABORTED The DNS server addresses to be set equal the current\r
678 configuration.\r
679 @retval EFI_SUCCESS The specified configuration data for the EFI IPv4\r
680 network stack was set.\r
681\r
682**/\r
683EFI_STATUS\r
684Ip4Config2SetDnsServerWorker (\r
d1050b9d
MK
685 IN IP4_CONFIG2_INSTANCE *Instance,\r
686 IN UINTN DataSize,\r
687 IN VOID *Data\r
9feefde0
SEHM
688 )\r
689{\r
d1050b9d
MK
690 UINTN OldIndex;\r
691 UINTN NewIndex;\r
692 EFI_IPv4_ADDRESS *OldDns;\r
693 EFI_IPv4_ADDRESS *NewDns;\r
694 UINTN OldDnsCount;\r
695 UINTN NewDnsCount;\r
696 IP4_CONFIG2_DATA_ITEM *Item;\r
697 BOOLEAN OneAdded;\r
698 VOID *Tmp;\r
699 IP4_ADDR DnsAddress;\r
9feefde0
SEHM
700\r
701 if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
702 return EFI_BAD_BUFFER_SIZE;\r
703 }\r
704\r
705 Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
d1050b9d 706 NewDns = (EFI_IPv4_ADDRESS *)Data;\r
9feefde0 707 OldDns = Item->Data.DnsServers;\r
d1102dba 708 NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
9feefde0
SEHM
709 OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
710 OneAdded = FALSE;\r
711\r
712 if (NewDnsCount != OldDnsCount) {\r
713 Tmp = AllocatePool (DataSize);\r
714 if (Tmp == NULL) {\r
715 return EFI_OUT_OF_RESOURCES;\r
716 }\r
717 } else {\r
718 Tmp = NULL;\r
719 }\r
720\r
721 for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {\r
722 CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));\r
01b5ac88 723 if (IP4_IS_UNSPECIFIED (NTOHL (DnsAddress)) || IP4_IS_LOCAL_BROADCAST (NTOHL (DnsAddress))) {\r
9feefde0
SEHM
724 //\r
725 // The dns server address must be unicast.\r
726 //\r
d52f9163
JW
727 if (Tmp != NULL) {\r
728 FreePool (Tmp);\r
729 }\r
d1050b9d 730\r
9feefde0
SEHM
731 return EFI_INVALID_PARAMETER;\r
732 }\r
733\r
9feefde0
SEHM
734 if (OneAdded) {\r
735 //\r
736 // If any address in the new setting is not in the old settings, skip the\r
737 // comparision below.\r
738 //\r
739 continue;\r
740 }\r
741\r
742 for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {\r
743 if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {\r
744 //\r
745 // If found break out.\r
746 //\r
747 break;\r
748 }\r
749 }\r
750\r
751 if (OldIndex == OldDnsCount) {\r
752 OneAdded = TRUE;\r
753 }\r
754 }\r
755\r
756 if (!OneAdded && (DataSize == Item->DataSize)) {\r
757 //\r
758 // No new item is added and the size is the same.\r
759 //\r
760 Item->Status = EFI_SUCCESS;\r
761 return EFI_ABORTED;\r
762 } else {\r
763 if (Tmp != NULL) {\r
764 if (Item->Data.Ptr != NULL) {\r
765 FreePool (Item->Data.Ptr);\r
d1102dba 766 }\r
d1050b9d 767\r
9feefde0
SEHM
768 Item->Data.Ptr = Tmp;\r
769 }\r
770\r
771 CopyMem (Item->Data.Ptr, Data, DataSize);\r
772 Item->DataSize = DataSize;\r
773 Item->Status = EFI_SUCCESS;\r
774 return EFI_SUCCESS;\r
775 }\r
776}\r
777\r
1f6729ff 778/**\r
779 Callback function when DHCP process finished. It will save the\r
780 retrieved IP configure parameter from DHCP to the NVRam.\r
781\r
782 @param Event The callback event\r
783 @param Context Opaque context to the callback\r
784\r
785 @return None\r
786\r
787**/\r
788VOID\r
789EFIAPI\r
790Ip4Config2OnDhcp4Complete (\r
d1050b9d
MK
791 IN EFI_EVENT Event,\r
792 IN VOID *Context\r
1f6729ff 793 )\r
794{\r
d1050b9d
MK
795 IP4_CONFIG2_INSTANCE *Instance;\r
796 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
797 EFI_STATUS Status;\r
798 IP4_ADDR StationAddress;\r
799 IP4_ADDR SubnetMask;\r
800 IP4_ADDR GatewayAddress;\r
801 UINT32 Index;\r
802 UINT32 OptionCount;\r
803 EFI_DHCP4_PACKET_OPTION **OptionList;\r
804\r
805 Instance = (IP4_CONFIG2_INSTANCE *)Context;\r
1f6729ff 806 ASSERT (Instance->Dhcp4 != NULL);\r
807\r
808 //\r
809 // Get the DHCP retrieved parameters\r
810 //\r
811 Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);\r
812\r
813 if (EFI_ERROR (Status)) {\r
814 goto Exit;\r
815 }\r
816\r
817 if (Dhcp4Mode.State == Dhcp4Bound) {\r
818 StationAddress = EFI_NTOHL (Dhcp4Mode.ClientAddress);\r
d1050b9d 819 SubnetMask = EFI_NTOHL (Dhcp4Mode.SubnetMask);\r
1f6729ff 820 GatewayAddress = EFI_NTOHL (Dhcp4Mode.RouterAddress);\r
821\r
822 Status = Ip4Config2SetDefaultIf (Instance, StationAddress, SubnetMask, GatewayAddress);\r
823 if (EFI_ERROR (Status)) {\r
824 goto Exit;\r
825 }\r
d1102dba 826\r
9feefde0
SEHM
827 //\r
828 // Parse the ACK to get required DNS server information.\r
829 //\r
830 OptionCount = 0;\r
831 OptionList = NULL;\r
832\r
d1050b9d 833 Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);\r
9feefde0
SEHM
834 if (Status != EFI_BUFFER_TOO_SMALL) {\r
835 goto Exit;\r
836 }\r
837\r
838 OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));\r
839 if (OptionList == NULL) {\r
840 goto Exit;\r
841 }\r
842\r
843 Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);\r
844 if (EFI_ERROR (Status)) {\r
845 FreePool (OptionList);\r
846 goto Exit;\r
847 }\r
848\r
849 for (Index = 0; Index < OptionCount; Index++) {\r
850 //\r
851 // Look for DNS Server opcode (6).\r
852 //\r
ac6c3d90 853 if (OptionList[Index]->OpCode == DHCP4_TAG_DNS_SERVER) {\r
9feefde0
SEHM
854 if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {\r
855 break;\r
856 }\r
857\r
858 Ip4Config2SetDnsServerWorker (Instance, OptionList[Index]->Length, &OptionList[Index]->Data[0]);\r
859 break;\r
860 }\r
861 }\r
862\r
863 FreePool (OptionList);\r
864\r
1f6729ff 865 Instance->DhcpSuccess = TRUE;\r
866 }\r
867\r
868Exit:\r
869 Ip4Config2CleanDhcp4 (Instance);\r
870 DispatchDpc ();\r
871}\r
872\r
1f6729ff 873/**\r
874 Start the DHCP configuration for this IP service instance.\r
875 It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the\r
876 DHCP configuration.\r
877\r
878 @param[in] Instance The IP4 config2 instance to configure\r
879\r
0a18956d 880 @retval EFI_SUCCESS The auto configuration is successfully started\r
1f6729ff 881 @retval Others Failed to start auto configuration.\r
882\r
883**/\r
884EFI_STATUS\r
885Ip4StartAutoConfig (\r
d1050b9d 886 IN IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 887 )\r
888{\r
d1050b9d
MK
889 IP4_SERVICE *IpSb;\r
890 EFI_DHCP4_PROTOCOL *Dhcp4;\r
891 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
892 EFI_DHCP4_PACKET_OPTION *OptionList[1];\r
893 IP4_CONFIG2_DHCP4_OPTION ParaList;\r
894 EFI_STATUS Status;\r
d1102dba 895\r
1f6729ff 896 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
897\r
898 if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
899 return EFI_SUCCESS;\r
900 }\r
901\r
902 //\r
903 // A host must not invoke DHCP configuration if it is already\r
6c585b52 904 // participating in the DHCP configuration process.\r
1f6729ff 905 //\r
906 if (Instance->Dhcp4Handle != NULL) {\r
907 return EFI_SUCCESS;\r
908 }\r
909\r
910 Status = NetLibCreateServiceChild (\r
911 IpSb->Controller,\r
912 IpSb->Image,\r
913 &gEfiDhcp4ServiceBindingProtocolGuid,\r
914 &Instance->Dhcp4Handle\r
915 );\r
916\r
917 if (Status == EFI_UNSUPPORTED) {\r
918 //\r
919 // No DHCPv4 Service Binding protocol, register a notify.\r
920 //\r
921 if (Instance->Dhcp4SbNotifyEvent == NULL) {\r
922 Instance->Dhcp4SbNotifyEvent = EfiCreateProtocolNotifyEvent (\r
923 &gEfiDhcp4ServiceBindingProtocolGuid,\r
924 TPL_CALLBACK,\r
925 Ip4Config2OnDhcp4SbInstalled,\r
d1050b9d 926 (VOID *)Instance,\r
1f6729ff 927 &Instance->Registration\r
928 );\r
929 }\r
930 }\r
931\r
932 if (EFI_ERROR (Status)) {\r
933 return Status;\r
934 }\r
935\r
936 if (Instance->Dhcp4SbNotifyEvent != NULL) {\r
937 gBS->CloseEvent (Instance->Dhcp4SbNotifyEvent);\r
938 }\r
939\r
940 Status = gBS->OpenProtocol (\r
941 Instance->Dhcp4Handle,\r
942 &gEfiDhcp4ProtocolGuid,\r
d1050b9d 943 (VOID **)&Instance->Dhcp4,\r
1f6729ff 944 IpSb->Image,\r
945 IpSb->Controller,\r
946 EFI_OPEN_PROTOCOL_BY_DRIVER\r
947 );\r
f3b108a8
JW
948 if (EFI_ERROR (Status)) {\r
949 NetLibDestroyServiceChild (\r
950 IpSb->Controller,\r
951 IpSb->Image,\r
952 &gEfiDhcp4ServiceBindingProtocolGuid,\r
953 Instance->Dhcp4Handle\r
954 );\r
1f6729ff 955\r
f3b108a8 956 Instance->Dhcp4Handle = NULL;\r
d1102dba 957\r
f3b108a8
JW
958 return Status;\r
959 }\r
1f6729ff 960\r
961 //\r
962 // Check the current DHCP status, if the DHCP process has\r
963 // already finished, return now.\r
964 //\r
965 Dhcp4 = Instance->Dhcp4;\r
966 Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
1f6729ff 967 if (Dhcp4Mode.State == Dhcp4Bound) {\r
968 Ip4Config2OnDhcp4Complete (NULL, Instance);\r
d1102dba 969\r
1f6729ff 970 return EFI_SUCCESS;\r
1f6729ff 971 }\r
972\r
973 //\r
974 // Try to start the DHCP process. Use most of the current\r
975 // DHCP configuration to avoid problems if some DHCP client\r
976 // yields the control of this DHCP service to us.\r
977 //\r
ac6c3d90 978 ParaList.Head.OpCode = DHCP4_TAG_PARA_LIST;\r
9feefde0 979 ParaList.Head.Length = 3;\r
ac6c3d90
ZL
980 ParaList.Head.Data[0] = DHCP4_TAG_NETMASK;\r
981 ParaList.Route = DHCP4_TAG_ROUTER;\r
982 ParaList.Dns = DHCP4_TAG_DNS_SERVER;\r
1f6729ff 983 OptionList[0] = &ParaList.Head;\r
984 Dhcp4Mode.ConfigData.OptionCount = 1;\r
985 Dhcp4Mode.ConfigData.OptionList = OptionList;\r
986\r
987 Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);\r
1f6729ff 988 if (EFI_ERROR (Status)) {\r
f3b108a8
JW
989 gBS->CloseProtocol (\r
990 Instance->Dhcp4Handle,\r
991 &gEfiDhcp4ProtocolGuid,\r
992 IpSb->Image,\r
993 IpSb->Controller\r
994 );\r
995\r
996 NetLibDestroyServiceChild (\r
997 IpSb->Controller,\r
998 IpSb->Image,\r
999 &gEfiDhcp4ServiceBindingProtocolGuid,\r
1000 Instance->Dhcp4Handle\r
1001 );\r
d1102dba 1002\r
f3b108a8 1003 Instance->Dhcp4 = NULL;\r
d1102dba 1004\r
f3b108a8 1005 Instance->Dhcp4Handle = NULL;\r
d1102dba 1006\r
1f6729ff 1007 return Status;\r
1008 }\r
d1102dba 1009\r
1f6729ff 1010 //\r
1011 // Start the DHCP process\r
1012 //\r
1013 Status = gBS->CreateEvent (\r
1014 EVT_NOTIFY_SIGNAL,\r
1015 TPL_CALLBACK,\r
1016 Ip4Config2OnDhcp4Complete,\r
1017 Instance,\r
1018 &Instance->Dhcp4Event\r
1019 );\r
1f6729ff 1020 if (EFI_ERROR (Status)) {\r
f3b108a8 1021 Ip4Config2DestroyDhcp4 (Instance);\r
1f6729ff 1022 return Status;\r
1023 }\r
1024\r
1025 Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);\r
1f6729ff 1026 if (EFI_ERROR (Status)) {\r
f3b108a8
JW
1027 Ip4Config2DestroyDhcp4 (Instance);\r
1028 gBS->CloseEvent (Instance->Dhcp4Event);\r
1029 Instance->Dhcp4Event = NULL;\r
d1102dba 1030\r
1f6729ff 1031 return Status;\r
1032 }\r
d1102dba 1033\r
f3b108a8 1034 IpSb->State = IP4_SERVICE_STARTED;\r
1f6729ff 1035 DispatchDpc ();\r
d1102dba 1036\r
1f6729ff 1037 return EFI_SUCCESS;\r
1f6729ff 1038}\r
1039\r
1f6729ff 1040/**\r
d1102dba 1041 The work function is to get the interface information of the communication\r
1f6729ff 1042 device this IP4_CONFIG2_INSTANCE manages.\r
1043\r
1044 @param[in] Instance Pointer to the IP4 config2 instance data.\r
1045 @param[in, out] DataSize On input, in bytes, the size of Data. On output, in\r
1046 bytes, the size of buffer required to store the specified\r
1047 configuration data.\r
1048 @param[in] Data The data buffer in which the configuration data is returned.\r
1049 Ignored if DataSize is ZERO.\r
1050\r
1051 @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified\r
1052 configuration data, and the required size is\r
1053 returned in DataSize.\r
1054 @retval EFI_SUCCESS The specified configuration data was obtained.\r
1055\r
1056**/\r
1057EFI_STATUS\r
1058Ip4Config2GetIfInfo (\r
d1050b9d
MK
1059 IN IP4_CONFIG2_INSTANCE *Instance,\r
1060 IN OUT UINTN *DataSize,\r
1061 IN VOID *Data OPTIONAL\r
1f6729ff 1062 )\r
1063{\r
d1050b9d
MK
1064 IP4_SERVICE *IpSb;\r
1065 UINTN Length;\r
1066 IP4_CONFIG2_DATA_ITEM *Item;\r
1067 EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;\r
1068 IP4_ADDR Address;\r
1f6729ff 1069\r
1070 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1071 Length = sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO);\r
1072\r
1073 if (IpSb->DefaultRouteTable != NULL) {\r
1074 Length += IpSb->DefaultRouteTable->TotalNum * sizeof (EFI_IP4_ROUTE_TABLE);\r
1075 }\r
d1102dba 1076\r
1f6729ff 1077 if (*DataSize < Length) {\r
1078 *DataSize = Length;\r
1079 return EFI_BUFFER_TOO_SMALL;\r
1080 }\r
1081\r
1082 //\r
1083 // Copy the fixed size part of the interface info.\r
1084 //\r
d1050b9d
MK
1085 Item = &Instance->DataItem[Ip4Config2DataTypeInterfaceInfo];\r
1086 IfInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *)Data;\r
1f6729ff 1087 CopyMem (IfInfo, Item->Data.Ptr, sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO));\r
1088\r
1089 //\r
1090 // Update the address info.\r
1091 //\r
1092 if (IpSb->DefaultInterface != NULL) {\r
1093 Address = HTONL (IpSb->DefaultInterface->Ip);\r
1094 CopyMem (&IfInfo->StationAddress, &Address, sizeof (EFI_IPv4_ADDRESS));\r
1095 Address = HTONL (IpSb->DefaultInterface->SubnetMask);\r
1096 CopyMem (&IfInfo->SubnetMask, &Address, sizeof (EFI_IPv4_ADDRESS));\r
1097 }\r
1098\r
1099 if (IpSb->DefaultRouteTable != NULL) {\r
1100 IfInfo->RouteTableSize = IpSb->DefaultRouteTable->TotalNum;\r
d1050b9d 1101 IfInfo->RouteTable = (EFI_IP4_ROUTE_TABLE *)((UINT8 *)Data + sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO));\r
1f6729ff 1102\r
d1102dba 1103 Ip4Config2BuildDefaultRouteTable (IpSb, IfInfo->RouteTable);\r
1f6729ff 1104 }\r
d1102dba 1105\r
1f6729ff 1106 return EFI_SUCCESS;\r
1107}\r
1108\r
1109/**\r
d1102dba 1110 The work function is to set the general configuration policy for the EFI IPv4 network\r
1f6729ff 1111 stack that is running on the communication device managed by this IP4_CONFIG2_INSTANCE.\r
1112 The policy will affect other configuration settings.\r
1113\r
1114 @param[in] Instance Pointer to the IP4 config2 instance data.\r
1115 @param[in] DataSize Size of the buffer pointed to by Data in bytes.\r
1116 @param[in] Data The data buffer to set.\r
1117\r
1118 @retval EFI_INVALID_PARAMETER The to be set policy is invalid.\r
1119 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.\r
1120 @retval EFI_ABORTED The new policy equals the current policy.\r
1121 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6\r
1122 network stack was set.\r
1123\r
1124**/\r
1125EFI_STATUS\r
1126Ip4Config2SetPolicy (\r
d1050b9d
MK
1127 IN IP4_CONFIG2_INSTANCE *Instance,\r
1128 IN UINTN DataSize,\r
1129 IN VOID *Data\r
1f6729ff 1130 )\r
1131{\r
d1050b9d
MK
1132 EFI_IP4_CONFIG2_POLICY NewPolicy;\r
1133 IP4_CONFIG2_DATA_ITEM *DataItem;\r
1134 IP4_SERVICE *IpSb;\r
1f6729ff 1135\r
1136 if (DataSize != sizeof (EFI_IP4_CONFIG2_POLICY)) {\r
1137 return EFI_BAD_BUFFER_SIZE;\r
1138 }\r
1139\r
d1050b9d 1140 NewPolicy = *((EFI_IP4_CONFIG2_POLICY *)Data);\r
1f6729ff 1141\r
1142 if (NewPolicy >= Ip4Config2PolicyMax) {\r
1143 return EFI_INVALID_PARAMETER;\r
1144 }\r
1145\r
1146 if (NewPolicy == Instance->Policy) {\r
d1050b9d 1147 if ((NewPolicy != Ip4Config2PolicyDhcp) || Instance->DhcpSuccess) {\r
7648748e
JW
1148 return EFI_ABORTED;\r
1149 }\r
1f6729ff 1150 } else {\r
24b41b75 1151 //\r
d1102dba 1152 // The policy is changed. Clean the ManualAddress, Gateway and DnsServers,\r
24b41b75
JW
1153 // shrink the variable data size, and fire up all the related events.\r
1154 //\r
d1050b9d 1155 DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
24b41b75
JW
1156 if (DataItem->Data.Ptr != NULL) {\r
1157 FreePool (DataItem->Data.Ptr);\r
1158 }\r
d1050b9d 1159\r
24b41b75
JW
1160 DataItem->Data.Ptr = NULL;\r
1161 DataItem->DataSize = 0;\r
1162 DataItem->Status = EFI_NOT_FOUND;\r
1163 NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);\r
1164\r
d1050b9d 1165 DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
24b41b75
JW
1166 if (DataItem->Data.Ptr != NULL) {\r
1167 FreePool (DataItem->Data.Ptr);\r
1168 }\r
d1050b9d 1169\r
24b41b75
JW
1170 DataItem->Data.Ptr = NULL;\r
1171 DataItem->DataSize = 0;\r
1172 DataItem->Status = EFI_NOT_FOUND;\r
1173 NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);\r
1174\r
d1050b9d 1175 DataItem = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
24b41b75
JW
1176 if (DataItem->Data.Ptr != NULL) {\r
1177 FreePool (DataItem->Data.Ptr);\r
1178 }\r
d1050b9d 1179\r
24b41b75
JW
1180 DataItem->Data.Ptr = NULL;\r
1181 DataItem->DataSize = 0;\r
1182 DataItem->Status = EFI_NOT_FOUND;\r
1183 NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);\r
d1102dba 1184\r
1f6729ff 1185 if (NewPolicy == Ip4Config2PolicyDhcp) {\r
eab40164 1186 SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_VOLATILE);\r
1f6729ff 1187 } else {\r
1188 //\r
1189 // The policy is changed from dhcp to static. Stop the DHCPv4 process\r
1190 // and destroy the DHCPv4 child.\r
1191 //\r
1192 if (Instance->Dhcp4Handle != NULL) {\r
1193 Ip4Config2DestroyDhcp4 (Instance);\r
1194 }\r
d1102dba 1195\r
1f6729ff 1196 //\r
1197 // Close the event.\r
1198 //\r
1199 if (Instance->Dhcp4Event != NULL) {\r
1200 gBS->CloseEvent (Instance->Dhcp4Event);\r
4f0f2316 1201 Instance->Dhcp4Event = NULL;\r
1f6729ff 1202 }\r
1203 }\r
1204 }\r
1205\r
1206 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1207 Ip4Config2OnPolicyChanged (IpSb, NewPolicy);\r
1208\r
1209 Instance->Policy = NewPolicy;\r
1210\r
1211 return EFI_SUCCESS;\r
1212}\r
1213\r
1214/**\r
d1102dba 1215 The work function is to set the station addresses manually for the EFI IPv4\r
1f6729ff 1216 network stack. It is only configurable when the policy is Ip4Config2PolicyStatic.\r
1217\r
1218 @param[in] Instance Pointer to the IP4 config2 instance data.\r
1219 @param[in] DataSize Size of the buffer pointed to by Data in bytes.\r
1220 @param[in] Data The data buffer to set.\r
1221\r
1222 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.\r
1223 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set\r
1224 under the current policy.\r
1225 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.\r
1226 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.\r
6c585b52 1227 @retval EFI_NOT_READY An asynchronous process is invoked to set the specified\r
1f6729ff 1228 configuration data, and the process is not finished.\r
1229 @retval EFI_ABORTED The manual addresses to be set equal current\r
1230 configuration.\r
1231 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6\r
1232 network stack was set.\r
1233\r
1234**/\r
1235EFI_STATUS\r
e826679b 1236Ip4Config2SetManualAddress (\r
d1050b9d
MK
1237 IN IP4_CONFIG2_INSTANCE *Instance,\r
1238 IN UINTN DataSize,\r
1239 IN VOID *Data\r
1f6729ff 1240 )\r
1241{\r
d1050b9d
MK
1242 EFI_IP4_CONFIG2_MANUAL_ADDRESS NewAddress;\r
1243 IP4_CONFIG2_DATA_ITEM *DataItem;\r
1244 EFI_STATUS Status;\r
1245 IP4_ADDR StationAddress;\r
1246 IP4_ADDR SubnetMask;\r
1247 VOID *Ptr;\r
1248 IP4_SERVICE *IpSb;\r
1249 IP4_INTERFACE *IpIf;\r
1250 IP4_ROUTE_TABLE *RouteTable;\r
11265704
JW
1251\r
1252 DataItem = NULL;\r
1253 Status = EFI_SUCCESS;\r
1254 Ptr = NULL;\r
1255 IpIf = NULL;\r
1256 RouteTable = NULL;\r
e371cc14
JW
1257\r
1258 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1f6729ff 1259\r
1260 ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);\r
1261\r
11265704 1262 if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0)) {\r
1f6729ff 1263 return EFI_BAD_BUFFER_SIZE;\r
1264 }\r
1265\r
1266 if (Instance->Policy != Ip4Config2PolicyStatic) {\r
1267 return EFI_WRITE_PROTECTED;\r
1268 }\r
1269\r
11265704 1270 DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
1f6729ff 1271\r
d1050b9d
MK
1272 if ((Data != NULL) && (DataSize != 0)) {\r
1273 NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *)Data);\r
818ba0ef 1274\r
11265704 1275 StationAddress = EFI_NTOHL (NewAddress.Address);\r
d1050b9d 1276 SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);\r
818ba0ef 1277\r
11265704
JW
1278 //\r
1279 // Check whether the StationAddress/SubnetMask pair is valid.\r
1280 //\r
1281 if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {\r
1282 return EFI_INVALID_PARAMETER;\r
1283 }\r
1f6729ff 1284\r
11265704
JW
1285 //\r
1286 // Store the new data, and init the DataItem status to EFI_NOT_READY because\r
1287 // we may have an asynchronous configuration process.\r
1288 //\r
1289 Ptr = AllocateCopyPool (DataSize, Data);\r
1290 if (Ptr == NULL) {\r
1291 return EFI_OUT_OF_RESOURCES;\r
1292 }\r
1f6729ff 1293\r
11265704
JW
1294 if (DataItem->Data.Ptr != NULL) {\r
1295 FreePool (DataItem->Data.Ptr);\r
1296 }\r
d1102dba 1297\r
11265704
JW
1298 DataItem->Data.Ptr = Ptr;\r
1299 DataItem->DataSize = DataSize;\r
1300 DataItem->Status = EFI_NOT_READY;\r
1301\r
1302 IpSb->Reconfig = TRUE;\r
d1050b9d 1303 Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
11265704
JW
1304\r
1305 DataItem->Status = Status;\r
1306\r
d1050b9d 1307 if (EFI_ERROR (DataItem->Status) && (DataItem->Status != EFI_NOT_READY)) {\r
11265704
JW
1308 if (Ptr != NULL) {\r
1309 FreePool (Ptr);\r
1310 }\r
d1050b9d 1311\r
d1102dba 1312 DataItem->Data.Ptr = NULL;\r
11265704
JW
1313 }\r
1314 } else {\r
1315 //\r
1316 // DataSize is 0 and Data is NULL, clean up the manual address.\r
1317 //\r
1318 if (DataItem->Data.Ptr != NULL) {\r
1319 FreePool (DataItem->Data.Ptr);\r
1320 }\r
d1050b9d 1321\r
11265704
JW
1322 DataItem->Data.Ptr = NULL;\r
1323 DataItem->DataSize = 0;\r
1324 DataItem->Status = EFI_NOT_FOUND;\r
1325\r
1326 //\r
1327 // Free the default router table and Interface, clean up the assemble table.\r
1328 //\r
1329 if (IpSb->DefaultInterface != NULL) {\r
1330 if (IpSb->DefaultRouteTable != NULL) {\r
1331 Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
d1102dba 1332 IpSb->DefaultRouteTable = NULL;\r
11265704 1333 }\r
1f6729ff 1334\r
11265704 1335 Ip4CancelReceive (IpSb->DefaultInterface);\r
1f6729ff 1336\r
11265704
JW
1337 Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
1338 IpSb->DefaultInterface = NULL;\r
1339 }\r
1340\r
1341 Ip4CleanAssembleTable (&IpSb->Assemble);\r
1342\r
1343 //\r
1344 // Create new default interface and route table.\r
d1102dba 1345 //\r
11265704
JW
1346 IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
1347 if (IpIf == NULL) {\r
1348 return EFI_OUT_OF_RESOURCES;\r
1349 }\r
1350\r
1351 RouteTable = Ip4CreateRouteTable ();\r
1352 if (RouteTable == NULL) {\r
1353 Ip4FreeInterface (IpIf, NULL);\r
1354 return EFI_OUT_OF_RESOURCES;\r
1355 }\r
d1102dba 1356\r
d1050b9d 1357 IpSb->DefaultInterface = IpIf;\r
11265704
JW
1358 InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
1359 IpSb->DefaultRouteTable = RouteTable;\r
1360 Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
1361\r
1362 //\r
d1102dba 1363 // Reset the State to unstarted.\r
11265704 1364 //\r
d1050b9d 1365 if ((IpSb->State == IP4_SERVICE_CONFIGED) || (IpSb->State == IP4_SERVICE_STARTED)) {\r
11265704 1366 IpSb->State = IP4_SERVICE_UNSTARTED;\r
1f6729ff 1367 }\r
1f6729ff 1368 }\r
1369\r
7278ce8c 1370 return Status;\r
1f6729ff 1371}\r
1372\r
1373/**\r
d1102dba
LG
1374 The work function is to set the gateway addresses manually for the EFI IPv4\r
1375 network stack that is running on the communication device that this EFI IPv4\r
1f6729ff 1376 Configuration Protocol manages. It is not configurable when the policy is\r
1377 Ip4Config2PolicyDhcp. The gateway addresses must be unicast IPv4 addresses.\r
1378\r
1379 @param[in] Instance The pointer to the IP4 config2 instance data.\r
1380 @param[in] DataSize The size of the buffer pointed to by Data in bytes.\r
1381 @param[in] Data The data buffer to set. This points to an array of\r
1382 EFI_IPv6_ADDRESS instances.\r
1383\r
1384 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.\r
1385 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set\r
1386 under the current policy.\r
1387 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.\r
1388 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to complete the operation.\r
1389 @retval EFI_ABORTED The manual gateway addresses to be set equal the\r
1390 current configuration.\r
1391 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6\r
1392 network stack was set.\r
1393\r
1394**/\r
1395EFI_STATUS\r
1396Ip4Config2SetGateway (\r
d1050b9d
MK
1397 IN IP4_CONFIG2_INSTANCE *Instance,\r
1398 IN UINTN DataSize,\r
1399 IN VOID *Data\r
1f6729ff 1400 )\r
1401{\r
d1050b9d
MK
1402 IP4_SERVICE *IpSb;\r
1403 IP4_CONFIG2_DATA_ITEM *DataItem;\r
1404 IP4_ADDR Gateway;\r
1405\r
1406 UINTN Index1;\r
1407 UINTN Index2;\r
1408 EFI_IPv4_ADDRESS *OldGateway;\r
1409 EFI_IPv4_ADDRESS *NewGateway;\r
1410 UINTN OldGatewayCount;\r
1411 UINTN NewGatewayCount;\r
1412 BOOLEAN OneRemoved;\r
1413 BOOLEAN OneAdded;\r
1414 VOID *Tmp;\r
1415\r
1416 OldGateway = NULL;\r
1417 NewGateway = NULL;\r
1418 OneRemoved = FALSE;\r
1419 OneAdded = FALSE;\r
1420 Tmp = NULL;\r
11265704
JW
1421\r
1422 if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv4_ADDRESS) != 0)) {\r
1f6729ff 1423 return EFI_BAD_BUFFER_SIZE;\r
1424 }\r
1425\r
1426 if (Instance->Policy != Ip4Config2PolicyStatic) {\r
1427 return EFI_WRITE_PROTECTED;\r
1428 }\r
1429\r
01b5ac88 1430 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1f6729ff 1431\r
11265704 1432 DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
1f6729ff 1433 OldGateway = DataItem->Data.Gateway;\r
1434 OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
1f6729ff 1435\r
1436 for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {\r
1437 //\r
11265704 1438 // Remove the old route entry.\r
1f6729ff 1439 //\r
1440 CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR));\r
1441 Ip4DelRoute (\r
1442 IpSb->DefaultRouteTable,\r
1443 IP4_ALLZERO_ADDRESS,\r
1444 IP4_ALLZERO_ADDRESS,\r
1445 NTOHL (Gateway)\r
1446 );\r
1447 OneRemoved = TRUE;\r
1f6729ff 1448 }\r
1449\r
d1050b9d
MK
1450 if ((Data != NULL) && (DataSize != 0)) {\r
1451 NewGateway = (EFI_IPv4_ADDRESS *)Data;\r
11265704
JW
1452 NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
1453 for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
1454 CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
1f6729ff 1455\r
d1102dba 1456 if ((IpSb->DefaultInterface->SubnetMask != 0) &&\r
d1050b9d
MK
1457 !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask))\r
1458 {\r
11265704
JW
1459 return EFI_INVALID_PARAMETER;\r
1460 }\r
1f6729ff 1461\r
11265704
JW
1462 for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {\r
1463 if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {\r
1464 return EFI_INVALID_PARAMETER;\r
1465 }\r
1466 }\r
1467 }\r
1f6729ff 1468\r
11265704
JW
1469 if (NewGatewayCount != OldGatewayCount) {\r
1470 Tmp = AllocatePool (DataSize);\r
1471 if (Tmp == NULL) {\r
1472 return EFI_OUT_OF_RESOURCES;\r
1f6729ff 1473 }\r
11265704
JW
1474 } else {\r
1475 Tmp = NULL;\r
1f6729ff 1476 }\r
1477\r
11265704
JW
1478 for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
1479 //\r
1480 // Add the new route entry.\r
1481 //\r
1482 CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
1483 Ip4AddRoute (\r
1484 IpSb->DefaultRouteTable,\r
1485 IP4_ALLZERO_ADDRESS,\r
1486 IP4_ALLZERO_ADDRESS,\r
1487 NTOHL (Gateway)\r
d1102dba 1488 );\r
11265704
JW
1489\r
1490 OneAdded = TRUE;\r
1491 }\r
1492\r
1493 if (!OneRemoved && !OneAdded) {\r
1494 DataItem->Status = EFI_SUCCESS;\r
1495 return EFI_ABORTED;\r
1496 } else {\r
1497 if (Tmp != NULL) {\r
1498 if (DataItem->Data.Ptr != NULL) {\r
1499 FreePool (DataItem->Data.Ptr);\r
1500 }\r
d1050b9d 1501\r
11265704
JW
1502 DataItem->Data.Ptr = Tmp;\r
1503 }\r
1504\r
1505 CopyMem (DataItem->Data.Ptr, Data, DataSize);\r
1506 DataItem->DataSize = DataSize;\r
1507 DataItem->Status = EFI_SUCCESS;\r
1508 }\r
1509 } else {\r
1510 //\r
1511 // DataSize is 0 and Data is NULL, clean up the Gateway address.\r
1512 //\r
1513 if (DataItem->Data.Ptr != NULL) {\r
1514 FreePool (DataItem->Data.Ptr);\r
1515 }\r
d1050b9d 1516\r
11265704
JW
1517 DataItem->Data.Ptr = NULL;\r
1518 DataItem->DataSize = 0;\r
1519 DataItem->Status = EFI_NOT_FOUND;\r
1f6729ff 1520 }\r
1521\r
11265704 1522 return EFI_SUCCESS;\r
1f6729ff 1523}\r
1524\r
1525/**\r
d1102dba
LG
1526 The work function is to set the DNS server list for the EFI IPv4 network\r
1527 stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL\r
1528 manages. It is not configurable when the policy is Ip4Config2PolicyDhcp.\r
1f6729ff 1529 The DNS server addresses must be unicast IPv4 addresses.\r
1530\r
1531 @param[in] Instance The pointer to the IP4 config2 instance data.\r
1532 @param[in] DataSize The size of the buffer pointed to by Data in bytes.\r
1533 @param[in] Data The data buffer to set, points to an array of\r
1534 EFI_IPv4_ADDRESS instances.\r
1535\r
1536 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.\r
1537 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set\r
1538 under the current policy.\r
1539 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.\r
1540 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.\r
1541 @retval EFI_ABORTED The DNS server addresses to be set equal the current\r
1542 configuration.\r
1543 @retval EFI_SUCCESS The specified configuration data for the EFI IPv4\r
1544 network stack was set.\r
1545\r
1546**/\r
1547EFI_STATUS\r
1548Ip4Config2SetDnsServer (\r
d1050b9d
MK
1549 IN IP4_CONFIG2_INSTANCE *Instance,\r
1550 IN UINTN DataSize,\r
1551 IN VOID *Data\r
1f6729ff 1552 )\r
1553{\r
d1050b9d
MK
1554 EFI_STATUS Status;\r
1555 IP4_CONFIG2_DATA_ITEM *Item;\r
eab40164 1556\r
11265704
JW
1557 Status = EFI_SUCCESS;\r
1558 Item = NULL;\r
eab40164 1559\r
1f6729ff 1560 if (Instance->Policy != Ip4Config2PolicyStatic) {\r
1561 return EFI_WRITE_PROTECTED;\r
1562 }\r
1563\r
eab40164
JW
1564 Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
1565\r
1566 if (DATA_ATTRIB_SET (Item->Attribute, DATA_ATTRIB_VOLATILE)) {\r
1567 REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE);\r
1568 }\r
1569\r
d1050b9d 1570 if ((Data != NULL) && (DataSize != 0)) {\r
11265704
JW
1571 Status = Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
1572 } else {\r
1573 //\r
d1102dba 1574 // DataSize is 0 and Data is NULL, clean up the DnsServer address.\r
11265704
JW
1575 //\r
1576 if (Item->Data.Ptr != NULL) {\r
1577 FreePool (Item->Data.Ptr);\r
1578 }\r
d1050b9d 1579\r
11265704
JW
1580 Item->Data.Ptr = NULL;\r
1581 Item->DataSize = 0;\r
1582 Item->Status = EFI_NOT_FOUND;\r
1583 }\r
d1102dba 1584\r
11265704 1585 return Status;\r
1f6729ff 1586}\r
1587\r
1588/**\r
1589 Generate the operational state of the interface this IP4 config2 instance manages\r
1590 and output in EFI_IP4_CONFIG2_INTERFACE_INFO.\r
1591\r
1592 @param[in] IpSb The pointer to the IP4 service binding instance.\r
1593 @param[out] IfInfo The pointer to the IP4 config2 interface information structure.\r
1594\r
1595**/\r
1596VOID\r
1597Ip4Config2InitIfInfo (\r
d1050b9d
MK
1598 IN IP4_SERVICE *IpSb,\r
1599 OUT EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo\r
1f6729ff 1600 )\r
1601{\r
770e463d
ZL
1602 UnicodeSPrint (\r
1603 IfInfo->Name,\r
1604 EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE,\r
702f2e15 1605 L"eth%d",\r
770e463d 1606 IpSb->Ip4Config2Instance.IfIndex\r
d1050b9d 1607 );\r
1f6729ff 1608\r
1609 IfInfo->IfType = IpSb->SnpMode.IfType;\r
1610 IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;\r
1611 CopyMem (&IfInfo->HwAddress, &IpSb->SnpMode.CurrentAddress, IfInfo->HwAddressSize);\r
1612}\r
1613\r
1f6729ff 1614/**\r
1615 Set the configuration for the EFI IPv4 network stack running on the communication\r
1616 device this EFI_IP4_CONFIG2_PROTOCOL instance manages.\r
1617\r
1618 This function is used to set the configuration data of type DataType for the EFI\r
1619 IPv4 network stack that is running on the communication device that this EFI IPv4\r
1620 Configuration Protocol instance manages.\r
1621\r
1622 DataSize is used to calculate the count of structure instances in the Data for\r
1623 a DataType in which multiple structure instances are allowed.\r
1624\r
1625 This function is always non-blocking. When setting some type of configuration data,\r
1626 an asynchronous process is invoked to check the correctness of the data, such as\r
1627 performing Duplicate Address Detection on the manually set local IPv4 addresses.\r
1628 EFI_NOT_READY is returned immediately to indicate that such an asynchronous process\r
1629 is invoked, and the process is not finished yet. The caller wanting to get the result\r
1630 of the asynchronous process is required to call RegisterDataNotify() to register an\r
1631 event on the specified configuration data. Once the event is signaled, the caller\r
1632 can call GetData() to obtain the configuration data and know the result.\r
1633 For other types of configuration data that do not require an asynchronous configuration\r
1634 process, the result of the operation is immediately returned.\r
1635\r
1636 @param[in] This The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.\r
1637 @param[in] DataType The type of data to set.\r
1638 @param[in] DataSize Size of the buffer pointed to by Data in bytes.\r
1639 @param[in] Data The data buffer to set. The type of the data buffer is\r
1640 associated with the DataType.\r
1641\r
1642 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6\r
1643 network stack was set successfully.\r
1644 @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:\r
1645 - This is NULL.\r
d1102dba 1646 - One or more fields in Data and DataSize do not match the\r
11265704 1647 requirement of the data type indicated by DataType.\r
1f6729ff 1648 @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified\r
1649 configuration data cannot be set under the current policy.\r
1650 @retval EFI_ACCESS_DENIED Another set operation on the specified configuration\r
1651 data is already in process.\r
1652 @retval EFI_NOT_READY An asynchronous process was invoked to set the specified\r
1653 configuration data, and the process is not finished yet.\r
1654 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type\r
1655 indicated by DataType.\r
1656 @retval EFI_UNSUPPORTED This DataType is not supported.\r
1657 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
1658 @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.\r
1659\r
1660**/\r
1661EFI_STATUS\r
1662EFIAPI\r
1663EfiIp4Config2SetData (\r
1664 IN EFI_IP4_CONFIG2_PROTOCOL *This,\r
1665 IN EFI_IP4_CONFIG2_DATA_TYPE DataType,\r
1666 IN UINTN DataSize,\r
1667 IN VOID *Data\r
1668 )\r
1669{\r
d1050b9d
MK
1670 EFI_TPL OldTpl;\r
1671 EFI_STATUS Status;\r
1672 IP4_CONFIG2_INSTANCE *Instance;\r
1673 IP4_SERVICE *IpSb;\r
1f6729ff 1674\r
d1050b9d 1675 if ((This == NULL) || ((Data == NULL) && (DataSize != 0)) || ((Data != NULL) && (DataSize == 0))) {\r
1f6729ff 1676 return EFI_INVALID_PARAMETER;\r
1677 }\r
1678\r
1679 if (DataType >= Ip4Config2DataTypeMaximum) {\r
1680 return EFI_UNSUPPORTED;\r
1681 }\r
1682\r
1683 Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);\r
1684 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1685 NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
1686\r
1f6729ff 1687 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1688\r
1689 Status = Instance->DataItem[DataType].Status;\r
1690 if (Status != EFI_NOT_READY) {\r
1f6729ff 1691 if (Instance->DataItem[DataType].SetData == NULL) {\r
1692 //\r
1693 // This type of data is readonly.\r
1694 //\r
1695 Status = EFI_WRITE_PROTECTED;\r
1696 } else {\r
1f6729ff 1697 Status = Instance->DataItem[DataType].SetData (Instance, DataSize, Data);\r
1698 if (!EFI_ERROR (Status)) {\r
1699 //\r
1700 // Fire up the events registered with this type of data.\r
1701 //\r
1702 NetMapIterate (&Instance->DataItem[DataType].EventMap, Ip4Config2SignalEvent, NULL);\r
1703 Ip4Config2WriteConfigData (IpSb->MacString, Instance);\r
1704 } else if (Status == EFI_ABORTED) {\r
1705 //\r
1706 // The SetData is aborted because the data to set is the same with\r
1707 // the one maintained.\r
1708 //\r
1709 Status = EFI_SUCCESS;\r
1710 NetMapIterate (&Instance->DataItem[DataType].EventMap, Ip4Config2SignalEvent, NULL);\r
1711 }\r
1712 }\r
1713 } else {\r
1714 //\r
6c585b52 1715 // Another asynchronous process is on the way.\r
1f6729ff 1716 //\r
1717 Status = EFI_ACCESS_DENIED;\r
1718 }\r
1719\r
1720 gBS->RestoreTPL (OldTpl);\r
1721\r
1722 return Status;\r
1723}\r
1724\r
1725/**\r
1726 Get the configuration data for the EFI IPv4 network stack running on the communication\r
1727 device that this EFI_IP4_CONFIG2_PROTOCOL instance manages.\r
1728\r
1729 This function returns the configuration data of type DataType for the EFI IPv4 network\r
1730 stack running on the communication device that this EFI IPv4 Configuration Protocol instance\r
1731 manages.\r
1732\r
1733 The caller is responsible for allocating the buffer used to return the specified\r
1734 configuration data. The required size will be returned to the caller if the size of\r
1735 the buffer is too small.\r
1736\r
1737 EFI_NOT_READY is returned if the specified configuration data is not ready due to an\r
1738 asynchronous configuration process already in progress. The caller can call RegisterDataNotify()\r
1739 to register an event on the specified configuration data. Once the asynchronous configuration\r
1740 process is finished, the event will be signaled, and a subsequent GetData() call will return\r
1741 the specified configuration data.\r
1742\r
1743 @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.\r
1744 @param[in] DataType The type of data to get.\r
1745 @param[in, out] DataSize On input, in bytes, the size of Data. On output, in bytes, the\r
1746 size of buffer required to store the specified configuration data.\r
1747 @param[in] Data The data buffer in which the configuration data is returned. The\r
1748 type of the data buffer is associated with the DataType.\r
1749 This is an optional parameter that may be NULL.\r
1750\r
1751 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1752 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:\r
1753 - This is NULL.\r
1754 - DataSize is NULL.\r
1755 - Data is NULL if *DataSize is not zero.\r
1756 @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data,\r
1757 and the required size is returned in DataSize.\r
1758 @retval EFI_NOT_READY The specified configuration data is not ready due to an\r
1759 asynchronous configuration process already in progress.\r
1760 @retval EFI_NOT_FOUND The specified configuration data is not found.\r
1761\r
1762**/\r
1763EFI_STATUS\r
1764EFIAPI\r
1765EfiIp4Config2GetData (\r
1766 IN EFI_IP4_CONFIG2_PROTOCOL *This,\r
1767 IN EFI_IP4_CONFIG2_DATA_TYPE DataType,\r
1768 IN OUT UINTN *DataSize,\r
1769 IN VOID *Data OPTIONAL\r
1770 )\r
1771{\r
d1050b9d
MK
1772 EFI_TPL OldTpl;\r
1773 EFI_STATUS Status;\r
1774 IP4_CONFIG2_INSTANCE *Instance;\r
1775 IP4_CONFIG2_DATA_ITEM *DataItem;\r
1f6729ff 1776\r
1777 if ((This == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) {\r
1778 return EFI_INVALID_PARAMETER;\r
1779 }\r
1780\r
1781 if (DataType >= Ip4Config2DataTypeMaximum) {\r
1782 return EFI_NOT_FOUND;\r
1783 }\r
1784\r
1785 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1786\r
1787 Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);\r
1788 DataItem = &Instance->DataItem[DataType];\r
1789\r
d1050b9d 1790 Status = Instance->DataItem[DataType].Status;\r
1f6729ff 1791 if (!EFI_ERROR (Status)) {\r
1f6729ff 1792 if (DataItem->GetData != NULL) {\r
1f6729ff 1793 Status = DataItem->GetData (Instance, DataSize, Data);\r
1794 } else if (*DataSize < Instance->DataItem[DataType].DataSize) {\r
1795 //\r
1796 // Update the buffer length.\r
1797 //\r
1798 *DataSize = Instance->DataItem[DataType].DataSize;\r
1799 Status = EFI_BUFFER_TOO_SMALL;\r
1800 } else {\r
1f6729ff 1801 *DataSize = Instance->DataItem[DataType].DataSize;\r
1802 CopyMem (Data, Instance->DataItem[DataType].Data.Ptr, *DataSize);\r
1803 }\r
1804 }\r
1805\r
1806 gBS->RestoreTPL (OldTpl);\r
1807\r
1808 return Status;\r
1809}\r
1810\r
1811/**\r
1812 Register an event that is signaled whenever a configuration process on the specified\r
1813 configuration data is done.\r
1814\r
1815 This function registers an event that is to be signaled whenever a configuration\r
1816 process on the specified configuration data is performed. An event can be registered\r
1817 for a different DataType simultaneously. The caller is responsible for determining\r
1818 which type of configuration data causes the signaling of the event in such an event.\r
1819\r
1820 @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.\r
1821 @param[in] DataType The type of data to unregister the event for.\r
1822 @param[in] Event The event to register.\r
1823\r
1824 @retval EFI_SUCCESS The notification event for the specified configuration data is\r
1825 registered.\r
1826 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.\r
1827 @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not\r
1828 supported.\r
1829 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
1830 @retval EFI_ACCESS_DENIED The Event is already registered for the DataType.\r
1831\r
1832**/\r
1833EFI_STATUS\r
1834EFIAPI\r
1835EfiIp4Config2RegisterDataNotify (\r
1836 IN EFI_IP4_CONFIG2_PROTOCOL *This,\r
1837 IN EFI_IP4_CONFIG2_DATA_TYPE DataType,\r
1838 IN EFI_EVENT Event\r
1839 )\r
1840{\r
d1050b9d
MK
1841 EFI_TPL OldTpl;\r
1842 EFI_STATUS Status;\r
1843 IP4_CONFIG2_INSTANCE *Instance;\r
1844 NET_MAP *EventMap;\r
1845 NET_MAP_ITEM *Item;\r
1f6729ff 1846\r
1847 if ((This == NULL) || (Event == NULL)) {\r
1848 return EFI_INVALID_PARAMETER;\r
1849 }\r
1850\r
1851 if (DataType >= Ip4Config2DataTypeMaximum) {\r
1852 return EFI_UNSUPPORTED;\r
1853 }\r
1854\r
d1050b9d 1855 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1f6729ff 1856\r
d1050b9d
MK
1857 Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);\r
1858 EventMap = &Instance->DataItem[DataType].EventMap;\r
1f6729ff 1859\r
1860 //\r
1861 // Check whether this event is already registered for this DataType.\r
1862 //\r
1863 Item = NetMapFindKey (EventMap, Event);\r
1864 if (Item == NULL) {\r
1f6729ff 1865 Status = NetMapInsertTail (EventMap, Event, NULL);\r
1866\r
1867 if (EFI_ERROR (Status)) {\r
1f6729ff 1868 Status = EFI_OUT_OF_RESOURCES;\r
1869 }\r
1f6729ff 1870 } else {\r
1f6729ff 1871 Status = EFI_ACCESS_DENIED;\r
1872 }\r
1873\r
1874 gBS->RestoreTPL (OldTpl);\r
1875\r
1876 return Status;\r
1877}\r
1878\r
1879/**\r
1880 Remove a previously registered event for the specified configuration data.\r
1881\r
1882 @param This The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.\r
1883 @param DataType The type of data to remove from the previously\r
1884 registered event.\r
1885 @param Event The event to be unregistered.\r
1886\r
1887 @retval EFI_SUCCESS The event registered for the specified\r
1888 configuration data was removed.\r
1889 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.\r
1890 @retval EFI_NOT_FOUND The Event has not been registered for the\r
1891 specified DataType.\r
1892\r
1893**/\r
1894EFI_STATUS\r
1895EFIAPI\r
1896EfiIp4Config2UnregisterDataNotify (\r
1897 IN EFI_IP4_CONFIG2_PROTOCOL *This,\r
1898 IN EFI_IP4_CONFIG2_DATA_TYPE DataType,\r
1899 IN EFI_EVENT Event\r
1900 )\r
1901{\r
d1050b9d
MK
1902 EFI_TPL OldTpl;\r
1903 EFI_STATUS Status;\r
1904 IP4_CONFIG2_INSTANCE *Instance;\r
1905 NET_MAP_ITEM *Item;\r
1f6729ff 1906\r
1907 if ((This == NULL) || (Event == NULL)) {\r
1908 return EFI_INVALID_PARAMETER;\r
1909 }\r
1910\r
1911 if (DataType >= Ip4Config2DataTypeMaximum) {\r
1912 return EFI_NOT_FOUND;\r
1913 }\r
1914\r
1915 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1916\r
1917 Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);\r
1918\r
1919 Item = NetMapFindKey (&Instance->DataItem[DataType].EventMap, Event);\r
1920 if (Item != NULL) {\r
1f6729ff 1921 NetMapRemoveItem (&Instance->DataItem[DataType].EventMap, Item, NULL);\r
1922 Status = EFI_SUCCESS;\r
1923 } else {\r
1f6729ff 1924 Status = EFI_NOT_FOUND;\r
1925 }\r
1926\r
1927 gBS->RestoreTPL (OldTpl);\r
1928\r
1929 return Status;\r
1930}\r
1931\r
1932/**\r
1933 Initialize an IP4_CONFIG2_INSTANCE.\r
1934\r
1935 @param[out] Instance The buffer of IP4_CONFIG2_INSTANCE to be initialized.\r
1936\r
1937 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.\r
1938 @retval EFI_SUCCESS The IP4_CONFIG2_INSTANCE initialized successfully.\r
1939\r
1940**/\r
1941EFI_STATUS\r
1942Ip4Config2InitInstance (\r
1943 OUT IP4_CONFIG2_INSTANCE *Instance\r
1944 )\r
1945{\r
d1050b9d
MK
1946 IP4_SERVICE *IpSb;\r
1947 IP4_CONFIG2_INSTANCE *TmpInstance;\r
1948 LIST_ENTRY *Entry;\r
1949 EFI_STATUS Status;\r
1950 UINTN Index;\r
1951 UINT16 IfIndex;\r
1952 IP4_CONFIG2_DATA_ITEM *DataItem;\r
1f6729ff 1953\r
1954 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1955\r
1956 Instance->Signature = IP4_CONFIG2_INSTANCE_SIGNATURE;\r
1957\r
1f6729ff 1958 //\r
1959 // Determine the index of this interface.\r
1960 //\r
1961 IfIndex = 0;\r
1962 NET_LIST_FOR_EACH (Entry, &mIp4Config2InstanceList) {\r
1963 TmpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_CONFIG2_INSTANCE, Link, IP4_CONFIG2_INSTANCE_SIGNATURE);\r
1964\r
1965 if (TmpInstance->IfIndex > IfIndex) {\r
1966 //\r
1967 // There is a sequence hole because some interface is down.\r
1968 //\r
1969 break;\r
1970 }\r
1971\r
1972 IfIndex++;\r
1973 }\r
1974\r
1975 Instance->IfIndex = IfIndex;\r
1976 NetListInsertBefore (Entry, &Instance->Link);\r
1977\r
1978 for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {\r
1979 //\r
1980 // Initialize the event map for each data item.\r
1981 //\r
1982 NetMapInit (&Instance->DataItem[Index].EventMap);\r
1983 }\r
1984\r
1f6729ff 1985 //\r
1986 // Initialize each data type: associate storage and set data size for the\r
1987 // fixed size data types, hook the SetData function, set the data attribute.\r
1988 //\r
1989 DataItem = &Instance->DataItem[Ip4Config2DataTypeInterfaceInfo];\r
1990 DataItem->GetData = Ip4Config2GetIfInfo;\r
1991 DataItem->Data.Ptr = &Instance->InterfaceInfo;\r
1992 DataItem->DataSize = sizeof (Instance->InterfaceInfo);\r
1993 SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED | DATA_ATTRIB_VOLATILE);\r
1994 Ip4Config2InitIfInfo (IpSb, &Instance->InterfaceInfo);\r
1995\r
1996 DataItem = &Instance->DataItem[Ip4Config2DataTypePolicy];\r
1997 DataItem->SetData = Ip4Config2SetPolicy;\r
1998 DataItem->Data.Ptr = &Instance->Policy;\r
1999 DataItem->DataSize = sizeof (Instance->Policy);\r
7648748e 2000 Instance->Policy = Ip4Config2PolicyStatic;\r
1f6729ff 2001 SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);\r
2002\r
d1050b9d
MK
2003 DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
2004 DataItem->SetData = Ip4Config2SetManualAddress;\r
2005 DataItem->Status = EFI_NOT_FOUND;\r
1f6729ff 2006\r
d1050b9d
MK
2007 DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
2008 DataItem->SetData = Ip4Config2SetGateway;\r
2009 DataItem->Status = EFI_NOT_FOUND;\r
1f6729ff 2010\r
d1050b9d
MK
2011 DataItem = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
2012 DataItem->SetData = Ip4Config2SetDnsServer;\r
2013 DataItem->Status = EFI_NOT_FOUND;\r
1f6729ff 2014\r
d1050b9d 2015 Instance->Configured = TRUE;\r
1f6729ff 2016\r
2017 //\r
2018 // Try to read the config data from NV variable.\r
d1102dba 2019 // If not found, write initialized config data into NV variable\r
7648748e 2020 // as a default config data.\r
1f6729ff 2021 //\r
2022 Status = Ip4Config2ReadConfigData (IpSb->MacString, Instance);\r
2023 if (Status == EFI_NOT_FOUND) {\r
2024 Status = Ip4Config2WriteConfigData (IpSb->MacString, Instance);\r
2025 }\r
2026\r
2027 if (EFI_ERROR (Status)) {\r
2028 return Status;\r
2029 }\r
d1102dba 2030\r
1f6729ff 2031 Instance->Ip4Config2.SetData = EfiIp4Config2SetData;\r
2032 Instance->Ip4Config2.GetData = EfiIp4Config2GetData;\r
2033 Instance->Ip4Config2.RegisterDataNotify = EfiIp4Config2RegisterDataNotify;\r
2034 Instance->Ip4Config2.UnregisterDataNotify = EfiIp4Config2UnregisterDataNotify;\r
2035\r
2036 //\r
2037 // Publish the IP4 configuration form\r
2038 //\r
2039 return Ip4Config2FormInit (Instance);\r
2040}\r
2041\r
1f6729ff 2042/**\r
2043 Release an IP4_CONFIG2_INSTANCE.\r
2044\r
2045 @param[in, out] Instance The buffer of IP4_CONFIG2_INSTANCE to be freed.\r
2046\r
2047**/\r
2048VOID\r
2049Ip4Config2CleanInstance (\r
2050 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
2051 )\r
2052{\r
d1050b9d
MK
2053 UINTN Index;\r
2054 IP4_CONFIG2_DATA_ITEM *DataItem;\r
1f6729ff 2055\r
2056 if (Instance->DeclineAddress != NULL) {\r
2057 FreePool (Instance->DeclineAddress);\r
2058 }\r
2059\r
2060 if (!Instance->Configured) {\r
d1050b9d 2061 return;\r
1f6729ff 2062 }\r
2063\r
2064 if (Instance->Dhcp4Handle != NULL) {\r
1f6729ff 2065 Ip4Config2DestroyDhcp4 (Instance);\r
2066 }\r
2067\r
2068 //\r
2069 // Close the event.\r
2070 //\r
2071 if (Instance->Dhcp4Event != NULL) {\r
2072 gBS->CloseEvent (Instance->Dhcp4Event);\r
4f0f2316 2073 Instance->Dhcp4Event = NULL;\r
1f6729ff 2074 }\r
2075\r
2076 for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {\r
1f6729ff 2077 DataItem = &Instance->DataItem[Index];\r
2078\r
2079 if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) {\r
2080 if (DataItem->Data.Ptr != NULL) {\r
2081 FreePool (DataItem->Data.Ptr);\r
2082 }\r
d1050b9d 2083\r
1f6729ff 2084 DataItem->Data.Ptr = NULL;\r
2085 DataItem->DataSize = 0;\r
2086 }\r
2087\r
2088 NetMapClean (&Instance->DataItem[Index].EventMap);\r
2089 }\r
2090\r
2091 Ip4Config2FormUnload (Instance);\r
2092\r
2093 RemoveEntryList (&Instance->Link);\r
2094}\r
2095\r
7648748e
JW
2096/**\r
2097 The event handle for IP4 auto reconfiguration. The original default\r
2098 interface and route table will be removed as the default.\r
2099\r
2100 @param[in] Context The IP4 service binding instance.\r
2101\r
2102**/\r
2103VOID\r
2104EFIAPI\r
2105Ip4AutoReconfigCallBackDpc (\r
d1050b9d 2106 IN VOID *Context\r
7648748e
JW
2107 )\r
2108{\r
d1050b9d 2109 IP4_SERVICE *IpSb;\r
7648748e 2110\r
d1050b9d 2111 IpSb = (IP4_SERVICE *)Context;\r
7648748e
JW
2112 NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
2113\r
2114 if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
2115 IpSb->State = IP4_SERVICE_UNSTARTED;\r
2116 }\r
d1102dba 2117\r
7648748e
JW
2118 IpSb->Reconfig = TRUE;\r
2119\r
2120 Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
2121\r
d1050b9d 2122 return;\r
7648748e
JW
2123}\r
2124\r
7648748e
JW
2125/**\r
2126 Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.\r
2127\r
2128 @param Event The event that is signalled.\r
2129 @param Context The IP4 service binding instance.\r
2130\r
2131**/\r
2132VOID\r
2133EFIAPI\r
2134Ip4AutoReconfigCallBack (\r
d1050b9d
MK
2135 IN EFI_EVENT Event,\r
2136 IN VOID *Context\r
7648748e
JW
2137 )\r
2138{\r
2139 //\r
2140 // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK\r
2141 //\r
2142 QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);\r
2143}\r