2 The implementation of EFI IPv4 Configuration II Protocol.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 LIST_ENTRY mIp4Config2InstanceList
= {&mIp4Config2InstanceList
, &mIp4Config2InstanceList
};
21 The event process routine when the DHCPv4 service binding protocol is installed
24 @param[in] Event Not used.
25 @param[in] Context Pointer to the IP4 config2 instance data.
30 Ip4Config2OnDhcp4SbInstalled (
36 Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.
38 @param[in, out] Instance The buffer of IP4 config2 instance to be freed.
40 @retval EFI_SUCCESS The child was successfully destroyed.
41 @retval Others Failed to destroy the child.
45 Ip4Config2DestroyDhcp4 (
46 IN OUT IP4_CONFIG2_INSTANCE
*Instance
51 EFI_DHCP4_PROTOCOL
*Dhcp4
;
53 Dhcp4
= Instance
->Dhcp4
;
54 ASSERT (Dhcp4
!= NULL
);
57 Dhcp4
->Configure (Dhcp4
, NULL
);
58 Instance
->Dhcp4
= NULL
;
60 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
63 // Close DHCPv4 protocol and destroy the child.
65 Status
= gBS
->CloseProtocol (
66 Instance
->Dhcp4Handle
,
67 &gEfiDhcp4ProtocolGuid
,
71 if (EFI_ERROR (Status
)) {
75 Status
= NetLibDestroyServiceChild (
78 &gEfiDhcp4ServiceBindingProtocolGuid
,
82 Instance
->Dhcp4Handle
= NULL
;
88 Update the current policy to NewPolicy. During the transition
89 period, the default router list
90 and address list in all interfaces will be released.
92 @param[in] IpSb The IP4 service binding instance.
93 @param[in] NewPolicy The new policy to be updated to.
97 Ip4Config2OnPolicyChanged (
99 IN EFI_IP4_CONFIG2_POLICY NewPolicy
103 IP4_ROUTE_TABLE
*RouteTable
;
106 // Currently there are only two policies: static and dhcp. Regardless of
107 // what transition is going on, i.e., static -> dhcp and dhcp ->
108 // static, we have to free default router table and all addresses.
111 if (IpSb
->DefaultInterface
!= NULL
) {
112 if (IpSb
->DefaultRouteTable
!= NULL
) {
113 Ip4FreeRouteTable (IpSb
->DefaultRouteTable
);
114 IpSb
->DefaultRouteTable
= NULL
;
117 Ip4CancelReceive (IpSb
->DefaultInterface
);
119 Ip4FreeInterface (IpSb
->DefaultInterface
, NULL
);
120 IpSb
->DefaultInterface
= NULL
;
123 Ip4CleanAssembleTable (&IpSb
->Assemble
);
126 // Create new default interface and route table.
128 IpIf
= Ip4CreateInterface (IpSb
->Mnp
, IpSb
->Controller
, IpSb
->Image
);
133 RouteTable
= Ip4CreateRouteTable ();
134 if (RouteTable
== NULL
) {
135 Ip4FreeInterface (IpIf
, NULL
);
139 IpSb
->DefaultInterface
= IpIf
;
140 InsertHeadList (&IpSb
->Interfaces
, &IpIf
->Link
);
141 IpSb
->DefaultRouteTable
= RouteTable
;
142 Ip4ReceiveFrame (IpIf
, NULL
, Ip4AccpetFrame
, IpSb
);
144 if (IpSb
->State
== IP4_SERVICE_CONFIGED
) {
145 IpSb
->State
= IP4_SERVICE_UNSTARTED
;
149 // Start the dhcp configuration.
151 if (NewPolicy
== Ip4Config2PolicyDhcp
) {
152 Ip4StartAutoConfig (&IpSb
->Ip4Config2Instance
);
158 Signal the registered event. It is the callback routine for NetMapIterate.
160 @param[in] Map Points to the list of registered event.
161 @param[in] Item The registered event.
162 @param[in] Arg Not used.
164 @retval EFI_SUCCESS The event was signaled successfully.
168 Ip4Config2SignalEvent (
170 IN NET_MAP_ITEM
*Item
,
174 gBS
->SignalEvent ((EFI_EVENT
) Item
->Key
);
180 Read the configuration data from variable storage according to the VarName and
181 gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the
182 data is corrupted, it clears the variable data to ZERO. Othewise, it outputs the
183 configuration data to IP4_CONFIG2_INSTANCE.
185 @param[in] VarName The pointer to the variable name
186 @param[in, out] Instance The pointer to the IP4 config2 instance data.
188 @retval EFI_NOT_FOUND The variable can not be found or already corrupted.
189 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.
190 @retval EFI_SUCCESS The configuration data was retrieved successfully.
194 Ip4Config2ReadConfigData (
196 IN OUT IP4_CONFIG2_INSTANCE
*Instance
201 IP4_CONFIG2_VARIABLE
*Variable
;
202 IP4_CONFIG2_DATA_ITEM
*DataItem
;
204 IP4_CONFIG2_DATA_RECORD DataRecord
;
208 // Try to read the configuration variable.
211 Status
= gRT
->GetVariable (
213 &gEfiIp4Config2ProtocolGuid
,
219 if (Status
== EFI_BUFFER_TOO_SMALL
) {
221 // Allocate buffer and read the config variable.
223 Variable
= AllocatePool (VarSize
);
224 if (Variable
== NULL
) {
225 return EFI_OUT_OF_RESOURCES
;
228 Status
= gRT
->GetVariable (
230 &gEfiIp4Config2ProtocolGuid
,
235 if (EFI_ERROR (Status
) || (UINT16
) (~NetblockChecksum ((UINT8
*) Variable
, (UINT32
) VarSize
)) != 0) {
237 // GetVariable still error or the variable is corrupted.
238 // Fall back to the default value.
243 // Remove the problematic variable and return EFI_NOT_FOUND, a new
244 // variable will be set again.
248 &gEfiIp4Config2ProtocolGuid
,
249 IP4_CONFIG2_VARIABLE_ATTRIBUTE
,
254 return EFI_NOT_FOUND
;
258 for (Index
= 0; Index
< Variable
->DataRecordCount
; Index
++) {
260 CopyMem (&DataRecord
, &Variable
->DataRecord
[Index
], sizeof (DataRecord
));
262 DataItem
= &Instance
->DataItem
[DataRecord
.DataType
];
263 if (DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
) &&
264 (DataItem
->DataSize
!= DataRecord
.DataSize
)
267 // Perhaps a corrupted data record...
272 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
)) {
274 // This data item has variable length data.
276 DataItem
->Data
.Ptr
= AllocatePool (DataRecord
.DataSize
);
277 if (DataItem
->Data
.Ptr
== NULL
) {
279 // no memory resource
285 Data
= (CHAR8
*) Variable
+ DataRecord
.Offset
;
286 CopyMem (DataItem
->Data
.Ptr
, Data
, DataRecord
.DataSize
);
288 DataItem
->DataSize
= DataRecord
.DataSize
;
289 DataItem
->Status
= EFI_SUCCESS
;
300 Write the configuration data from IP4_CONFIG2_INSTANCE to variable storage.
302 @param[in] VarName The pointer to the variable name.
303 @param[in] Instance The pointer to the IP4 config2 instance data.
305 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.
306 @retval EFI_SUCCESS The configuration data is written successfully.
310 Ip4Config2WriteConfigData (
312 IN IP4_CONFIG2_INSTANCE
*Instance
317 IP4_CONFIG2_DATA_ITEM
*DataItem
;
318 IP4_CONFIG2_VARIABLE
*Variable
;
319 IP4_CONFIG2_DATA_RECORD
*DataRecord
;
323 VarSize
= sizeof (IP4_CONFIG2_VARIABLE
) - sizeof (IP4_CONFIG2_DATA_RECORD
);
325 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
327 DataItem
= &Instance
->DataItem
[Index
];
328 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_VOLATILE
) && !EFI_ERROR (DataItem
->Status
)) {
330 VarSize
+= sizeof (IP4_CONFIG2_DATA_RECORD
) + DataItem
->DataSize
;
334 Variable
= AllocatePool (VarSize
);
335 if (Variable
== NULL
) {
336 return EFI_OUT_OF_RESOURCES
;
339 Heap
= (CHAR8
*) Variable
+ VarSize
;
340 Variable
->DataRecordCount
= 0;
342 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
344 DataItem
= &Instance
->DataItem
[Index
];
345 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_VOLATILE
) && !EFI_ERROR (DataItem
->Status
)) {
347 Heap
-= DataItem
->DataSize
;
348 CopyMem (Heap
, DataItem
->Data
.Ptr
, DataItem
->DataSize
);
350 DataRecord
= &Variable
->DataRecord
[Variable
->DataRecordCount
];
351 DataRecord
->DataType
= (EFI_IP4_CONFIG2_DATA_TYPE
) Index
;
352 DataRecord
->DataSize
= (UINT32
) DataItem
->DataSize
;
353 DataRecord
->Offset
= (UINT16
) (Heap
- (CHAR8
*) Variable
);
355 Variable
->DataRecordCount
++;
359 Variable
->Checksum
= 0;
360 Variable
->Checksum
= (UINT16
) ~NetblockChecksum ((UINT8
*) Variable
, (UINT32
) VarSize
);
362 Status
= gRT
->SetVariable (
364 &gEfiIp4Config2ProtocolGuid
,
365 IP4_CONFIG2_VARIABLE_ATTRIBUTE
,
377 Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData.
378 The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the
381 @param[in] IpSb The IP4 service binding instance.
382 @param[out] Table The built IP4 route table.
384 @retval EFI_SUCCESS The route table is successfully build
385 @retval EFI_NOT_FOUND Failed to allocate the memory for the rotue table.
389 Ip4Config2BuildDefaultRouteTable (
390 IN IP4_SERVICE
*IpSb
,
391 OUT EFI_IP4_ROUTE_TABLE
*Table
395 IP4_ROUTE_ENTRY
*RtEntry
;
399 if (IpSb
->DefaultRouteTable
== NULL
) {
400 return EFI_NOT_FOUND
;
403 Count
= IpSb
->DefaultRouteTable
->TotalNum
;
406 return EFI_NOT_FOUND
;
410 // Copy the route entry to EFI route table. Keep the order of
411 // route entry copied from most specific to default route. That
412 // is, interlevel the route entry from the instance's route area
413 // and those from the default route table's route area.
417 for (Index
= IP4_MASK_NUM
- 1; Index
>= 0; Index
--) {
419 NET_LIST_FOR_EACH (Entry
, &(IpSb
->DefaultRouteTable
->RouteArea
[Index
])) {
420 RtEntry
= NET_LIST_USER_STRUCT (Entry
, IP4_ROUTE_ENTRY
, Link
);
422 EFI_IP4 (Table
[Count
].SubnetAddress
) = HTONL (RtEntry
->Dest
& RtEntry
->Netmask
);
423 EFI_IP4 (Table
[Count
].SubnetMask
) = HTONL (RtEntry
->Netmask
);
424 EFI_IP4 (Table
[Count
].GatewayAddress
) = HTONL (RtEntry
->NextHop
);
435 The event process routine when the DHCPv4 service binding protocol is installed
438 @param[in] Event Not used.
439 @param[in] Context The pointer to the IP4 config2 instance data.
444 Ip4Config2OnDhcp4SbInstalled (
449 IP4_CONFIG2_INSTANCE
*Instance
;
451 Instance
= (IP4_CONFIG2_INSTANCE
*) Context
;
453 if ((Instance
->Dhcp4Handle
!= NULL
) || (Instance
->Policy
!= Ip4Config2PolicyDhcp
)) {
455 // The DHCP4 child is already created or the policy is no longer DHCP.
460 Ip4StartAutoConfig (Instance
);
464 Set the station address and subnetmask for the default interface.
466 @param[in] Instance The pointer to the IP4 config2 instance data.
467 @param[in] StationAddress Ip address to be set.
468 @param[in] SubnetMask Subnet to be set.
470 @retval EFI_SUCCESS Set default address successful.
471 @retval Others Some errors occur in setting.
475 Ip4Config2SetDefaultAddr (
476 IN IP4_CONFIG2_INSTANCE
*Instance
,
477 IN IP4_ADDR StationAddress
,
478 IN IP4_ADDR SubnetMask
484 IP4_PROTOCOL
*Ip4Instance
;
485 EFI_ARP_PROTOCOL
*Arp
;
488 IP4_ROUTE_TABLE
*RouteTable
;
490 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
491 IpIf
= IpSb
->DefaultInterface
;
492 ASSERT (IpIf
!= NULL
);
494 if ((IpIf
->Ip
== StationAddress
) && (IpIf
->SubnetMask
== SubnetMask
)) {
499 // The default address is changed, free the previous interface first.
501 if (IpSb
->DefaultRouteTable
!= NULL
) {
502 Ip4FreeRouteTable (IpSb
->DefaultRouteTable
);
503 IpSb
->DefaultRouteTable
= NULL
;
506 Ip4CancelReceive (IpSb
->DefaultInterface
);
507 Ip4FreeInterface (IpSb
->DefaultInterface
, NULL
);
508 IpSb
->DefaultInterface
= NULL
;
510 // Create new default interface and route table.
512 IpIf
= Ip4CreateInterface (IpSb
->Mnp
, IpSb
->Controller
, IpSb
->Image
);
514 return EFI_OUT_OF_RESOURCES
;
517 RouteTable
= Ip4CreateRouteTable ();
518 if (RouteTable
== NULL
) {
519 Ip4FreeInterface (IpIf
, NULL
);
520 return EFI_OUT_OF_RESOURCES
;
523 IpSb
->DefaultInterface
= IpIf
;
524 InsertHeadList (&IpSb
->Interfaces
, &IpIf
->Link
);
525 IpSb
->DefaultRouteTable
= RouteTable
;
526 Ip4ReceiveFrame (IpIf
, NULL
, Ip4AccpetFrame
, IpSb
);
528 if (IpSb
->State
== IP4_SERVICE_CONFIGED
) {
529 IpSb
->State
= IP4_SERVICE_UNSTARTED
;
532 Status
= Ip4SetAddress (IpIf
, StationAddress
, SubnetMask
);
533 if (EFI_ERROR (Status
)) {
537 if (IpIf
->Arp
!= NULL
) {
539 // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address,
540 // but some IP children may have referenced the default interface before it is configured,
541 // these IP instances also consume this ARP protocol so they need to open it BY_CHILD_CONTROLLER.
544 NET_LIST_FOR_EACH (Entry
, &IpIf
->IpInstances
) {
545 Ip4Instance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_PROTOCOL
, AddrLink
, IP4_PROTOCOL_SIGNATURE
);
546 Status
= gBS
->OpenProtocol (
548 &gEfiArpProtocolGuid
,
550 gIp4DriverBinding
.DriverBindingHandle
,
552 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
554 if (EFI_ERROR (Status
)) {
561 IpSb
->DefaultRouteTable
,
568 // Add a route for the connected network.
570 Subnet
= StationAddress
& SubnetMask
;
573 IpSb
->DefaultRouteTable
,
579 IpSb
->State
= IP4_SERVICE_CONFIGED
;
584 Set the station address, subnetmask and gateway address for the default interface.
586 @param[in] Instance The pointer to the IP4 config2 instance data.
587 @param[in] StationAddress Ip address to be set.
588 @param[in] SubnetMask Subnet to be set.
589 @param[in] GatewayAddress Gateway to be set.
591 @retval EFI_SUCCESS Set default If successful.
592 @retval Others Errors occur as indicated.
596 Ip4Config2SetDefaultIf (
597 IN IP4_CONFIG2_INSTANCE
*Instance
,
598 IN IP4_ADDR StationAddress
,
599 IN IP4_ADDR SubnetMask
,
600 IN IP4_ADDR GatewayAddress
606 Status
= Ip4Config2SetDefaultAddr (Instance
, StationAddress
, SubnetMask
);
607 if (EFI_ERROR (Status
)) {
612 // Create a route if there is a default router.
614 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
615 if (GatewayAddress
!= IP4_ALLZERO_ADDRESS
) {
617 IpSb
->DefaultRouteTable
,
629 Release all the DHCP related resources.
631 @param Instance The IP4 config2 instance.
637 Ip4Config2CleanDhcp4 (
638 IN IP4_CONFIG2_INSTANCE
*Instance
643 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
645 if (Instance
->Dhcp4
!= NULL
) {
646 Instance
->Dhcp4
->Stop (Instance
->Dhcp4
);
649 Instance
->Dhcp4Handle
,
650 &gEfiDhcp4ProtocolGuid
,
655 Instance
->Dhcp4
= NULL
;
658 if (Instance
->Dhcp4Handle
!= NULL
) {
659 NetLibDestroyServiceChild (
662 &gEfiDhcp4ServiceBindingProtocolGuid
,
663 Instance
->Dhcp4Handle
666 Instance
->Dhcp4Handle
= NULL
;
669 if (Instance
->Dhcp4Event
!= NULL
) {
670 gBS
->CloseEvent (Instance
->Dhcp4Event
);
671 Instance
->Dhcp4Event
= NULL
;
677 Callback function when DHCP process finished. It will save the
678 retrieved IP configure parameter from DHCP to the NVRam.
680 @param Event The callback event
681 @param Context Opaque context to the callback
688 Ip4Config2OnDhcp4Complete (
693 IP4_CONFIG2_INSTANCE
*Instance
;
694 EFI_DHCP4_MODE_DATA Dhcp4Mode
;
696 IP4_ADDR StationAddress
;
698 IP4_ADDR GatewayAddress
;
700 Instance
= (IP4_CONFIG2_INSTANCE
*) Context
;
701 ASSERT (Instance
->Dhcp4
!= NULL
);
704 // Get the DHCP retrieved parameters
706 Status
= Instance
->Dhcp4
->GetModeData (Instance
->Dhcp4
, &Dhcp4Mode
);
708 if (EFI_ERROR (Status
)) {
712 if (Dhcp4Mode
.State
== Dhcp4Bound
) {
713 StationAddress
= EFI_NTOHL (Dhcp4Mode
.ClientAddress
);
714 SubnetMask
= EFI_NTOHL (Dhcp4Mode
.SubnetMask
);
715 GatewayAddress
= EFI_NTOHL (Dhcp4Mode
.RouterAddress
);
717 Status
= Ip4Config2SetDefaultIf (Instance
, StationAddress
, SubnetMask
, GatewayAddress
);
718 if (EFI_ERROR (Status
)) {
722 Instance
->DhcpSuccess
= TRUE
;
726 Ip4Config2CleanDhcp4 (Instance
);
732 Start the DHCP configuration for this IP service instance.
733 It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the
736 @param[in] Instance The IP4 config2 instance to configure
738 @retval EFI_SUCCESS The auto configuration is successfull started
739 @retval Others Failed to start auto configuration.
744 IN IP4_CONFIG2_INSTANCE
*Instance
748 EFI_DHCP4_PROTOCOL
*Dhcp4
;
749 EFI_DHCP4_MODE_DATA Dhcp4Mode
;
750 EFI_DHCP4_PACKET_OPTION
*OptionList
[1];
751 IP4_CONFIG2_DHCP4_OPTION ParaList
;
755 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
757 if (IpSb
->State
> IP4_SERVICE_UNSTARTED
) {
762 // A host must not invoke DHCP configuration if it is already
763 // participating in the DHCP configuraiton process.
765 if (Instance
->Dhcp4Handle
!= NULL
) {
769 Status
= NetLibCreateServiceChild (
772 &gEfiDhcp4ServiceBindingProtocolGuid
,
773 &Instance
->Dhcp4Handle
776 if (Status
== EFI_UNSUPPORTED
) {
778 // No DHCPv4 Service Binding protocol, register a notify.
780 if (Instance
->Dhcp4SbNotifyEvent
== NULL
) {
781 Instance
->Dhcp4SbNotifyEvent
= EfiCreateProtocolNotifyEvent (
782 &gEfiDhcp4ServiceBindingProtocolGuid
,
784 Ip4Config2OnDhcp4SbInstalled
,
786 &Instance
->Registration
791 if (EFI_ERROR (Status
)) {
795 if (Instance
->Dhcp4SbNotifyEvent
!= NULL
) {
796 gBS
->CloseEvent (Instance
->Dhcp4SbNotifyEvent
);
799 Status
= gBS
->OpenProtocol (
800 Instance
->Dhcp4Handle
,
801 &gEfiDhcp4ProtocolGuid
,
802 (VOID
**) &Instance
->Dhcp4
,
805 EFI_OPEN_PROTOCOL_BY_DRIVER
807 ASSERT_EFI_ERROR (Status
);
811 // Check the current DHCP status, if the DHCP process has
812 // already finished, return now.
814 Dhcp4
= Instance
->Dhcp4
;
815 Status
= Dhcp4
->GetModeData (Dhcp4
, &Dhcp4Mode
);
817 if (Dhcp4Mode
.State
== Dhcp4Bound
) {
818 Ip4Config2OnDhcp4Complete (NULL
, Instance
);
824 // Try to start the DHCP process. Use most of the current
825 // DHCP configuration to avoid problems if some DHCP client
826 // yields the control of this DHCP service to us.
828 ParaList
.Head
.OpCode
= DHCP_TAG_PARA_LIST
;
829 ParaList
.Head
.Length
= 2;
830 ParaList
.Head
.Data
[0] = DHCP_TAG_NETMASK
;
831 ParaList
.Route
= DHCP_TAG_ROUTER
;
832 OptionList
[0] = &ParaList
.Head
;
833 Dhcp4Mode
.ConfigData
.OptionCount
= 1;
834 Dhcp4Mode
.ConfigData
.OptionList
= OptionList
;
836 Status
= Dhcp4
->Configure (Dhcp4
, &Dhcp4Mode
.ConfigData
);
838 if (EFI_ERROR (Status
)) {
843 // Start the DHCP process
845 Status
= gBS
->CreateEvent (
848 Ip4Config2OnDhcp4Complete
,
850 &Instance
->Dhcp4Event
853 if (EFI_ERROR (Status
)) {
857 Status
= Dhcp4
->Start (Dhcp4
, Instance
->Dhcp4Event
);
859 if (EFI_ERROR (Status
)) {
863 IpSb
->State
= IP4_SERVICE_STARTED
;
872 The work function is to get the interface information of the communication
873 device this IP4_CONFIG2_INSTANCE manages.
875 @param[in] Instance Pointer to the IP4 config2 instance data.
876 @param[in, out] DataSize On input, in bytes, the size of Data. On output, in
877 bytes, the size of buffer required to store the specified
879 @param[in] Data The data buffer in which the configuration data is returned.
880 Ignored if DataSize is ZERO.
882 @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified
883 configuration data, and the required size is
884 returned in DataSize.
885 @retval EFI_SUCCESS The specified configuration data was obtained.
889 Ip4Config2GetIfInfo (
890 IN IP4_CONFIG2_INSTANCE
*Instance
,
891 IN OUT UINTN
*DataSize
,
892 IN VOID
*Data OPTIONAL
898 IP4_CONFIG2_DATA_ITEM
*Item
;
899 EFI_IP4_CONFIG2_INTERFACE_INFO
*IfInfo
;
902 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
903 Length
= sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO
);
905 if (IpSb
->DefaultRouteTable
!= NULL
) {
906 Length
+= IpSb
->DefaultRouteTable
->TotalNum
* sizeof (EFI_IP4_ROUTE_TABLE
);
909 if (*DataSize
< Length
) {
911 return EFI_BUFFER_TOO_SMALL
;
915 // Copy the fixed size part of the interface info.
917 Item
= &Instance
->DataItem
[Ip4Config2DataTypeInterfaceInfo
];
918 IfInfo
= (EFI_IP4_CONFIG2_INTERFACE_INFO
*) Data
;
919 CopyMem (IfInfo
, Item
->Data
.Ptr
, sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO
));
922 // Update the address info.
924 if (IpSb
->DefaultInterface
!= NULL
) {
925 Address
= HTONL (IpSb
->DefaultInterface
->Ip
);
926 CopyMem (&IfInfo
->StationAddress
, &Address
, sizeof (EFI_IPv4_ADDRESS
));
927 Address
= HTONL (IpSb
->DefaultInterface
->SubnetMask
);
928 CopyMem (&IfInfo
->SubnetMask
, &Address
, sizeof (EFI_IPv4_ADDRESS
));
931 if (IpSb
->DefaultRouteTable
!= NULL
) {
932 IfInfo
->RouteTableSize
= IpSb
->DefaultRouteTable
->TotalNum
;
933 IfInfo
->RouteTable
= (EFI_IP4_ROUTE_TABLE
*) ((UINT8
*) Data
+ sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO
));
935 Ip4Config2BuildDefaultRouteTable (IpSb
, IfInfo
->RouteTable
);
942 The work function is to set the general configuration policy for the EFI IPv4 network
943 stack that is running on the communication device managed by this IP4_CONFIG2_INSTANCE.
944 The policy will affect other configuration settings.
946 @param[in] Instance Pointer to the IP4 config2 instance data.
947 @param[in] DataSize Size of the buffer pointed to by Data in bytes.
948 @param[in] Data The data buffer to set.
950 @retval EFI_INVALID_PARAMETER The to be set policy is invalid.
951 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
952 @retval EFI_ABORTED The new policy equals the current policy.
953 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
954 network stack was set.
958 Ip4Config2SetPolicy (
959 IN IP4_CONFIG2_INSTANCE
*Instance
,
964 EFI_IP4_CONFIG2_POLICY NewPolicy
;
965 IP4_CONFIG2_DATA_ITEM
*DataItem
;
968 if (DataSize
!= sizeof (EFI_IP4_CONFIG2_POLICY
)) {
969 return EFI_BAD_BUFFER_SIZE
;
972 NewPolicy
= *((EFI_IP4_CONFIG2_POLICY
*) Data
);
974 if (NewPolicy
>= Ip4Config2PolicyMax
) {
975 return EFI_INVALID_PARAMETER
;
978 if (NewPolicy
== Instance
->Policy
) {
981 if (NewPolicy
== Ip4Config2PolicyDhcp
) {
983 // The policy is changed from static to dhcp:
984 // Clean the ManualAddress, Gateway and DnsServers, shrink the variable
985 // data size, and fire up all the related events.
987 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeManualAddress
];
988 if (DataItem
->Data
.Ptr
!= NULL
) {
989 FreePool (DataItem
->Data
.Ptr
);
991 DataItem
->Data
.Ptr
= NULL
;
992 DataItem
->DataSize
= 0;
993 DataItem
->Status
= EFI_NOT_FOUND
;
994 NetMapIterate (&DataItem
->EventMap
, Ip4Config2SignalEvent
, NULL
);
996 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeGateway
];
997 if (DataItem
->Data
.Ptr
!= NULL
) {
998 FreePool (DataItem
->Data
.Ptr
);
1000 DataItem
->Data
.Ptr
= NULL
;
1001 DataItem
->DataSize
= 0;
1002 DataItem
->Status
= EFI_NOT_FOUND
;
1003 NetMapIterate (&DataItem
->EventMap
, Ip4Config2SignalEvent
, NULL
);
1005 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeDnsServer
];
1006 if (DataItem
->Data
.Ptr
!= NULL
) {
1007 FreePool (DataItem
->Data
.Ptr
);
1009 DataItem
->Data
.Ptr
= NULL
;
1010 DataItem
->DataSize
= 0;
1011 DataItem
->Status
= EFI_NOT_FOUND
;
1012 NetMapIterate (&DataItem
->EventMap
, Ip4Config2SignalEvent
, NULL
);
1015 // The policy is changed from dhcp to static. Stop the DHCPv4 process
1016 // and destroy the DHCPv4 child.
1018 if (Instance
->Dhcp4Handle
!= NULL
) {
1019 Ip4Config2DestroyDhcp4 (Instance
);
1025 if (Instance
->Dhcp4Event
!= NULL
) {
1026 gBS
->CloseEvent (Instance
->Dhcp4Event
);
1031 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1032 Ip4Config2OnPolicyChanged (IpSb
, NewPolicy
);
1034 Instance
->Policy
= NewPolicy
;
1040 The work function is to set the station addresses manually for the EFI IPv4
1041 network stack. It is only configurable when the policy is Ip4Config2PolicyStatic.
1043 @param[in] Instance Pointer to the IP4 config2 instance data.
1044 @param[in] DataSize Size of the buffer pointed to by Data in bytes.
1045 @param[in] Data The data buffer to set.
1047 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
1048 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
1049 under the current policy.
1050 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
1051 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.
1052 @retval EFI_NOT_READY An asynchrous process is invoked to set the specified
1053 configuration data, and the process is not finished.
1054 @retval EFI_ABORTED The manual addresses to be set equal current
1056 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
1057 network stack was set.
1061 Ip4Config2SetMaunualAddress (
1062 IN IP4_CONFIG2_INSTANCE
*Instance
,
1067 EFI_IP4_CONFIG2_MANUAL_ADDRESS NewAddress
;
1068 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1070 IP4_ADDR StationAddress
;
1071 IP4_ADDR SubnetMask
;
1074 ASSERT (Instance
->DataItem
[Ip4Config2DataTypeManualAddress
].Status
!= EFI_NOT_READY
);
1076 if (((DataSize
% sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
)) != 0) || (DataSize
== 0)) {
1077 return EFI_BAD_BUFFER_SIZE
;
1080 if (Instance
->Policy
!= Ip4Config2PolicyStatic
) {
1081 return EFI_WRITE_PROTECTED
;
1084 NewAddress
= *((EFI_IP4_CONFIG2_MANUAL_ADDRESS
*) Data
);
1087 // Store the new data, and init the DataItem status to EFI_NOT_READY because
1088 // we may have an asynchronous configuration process.
1090 Ptr
= AllocateCopyPool (DataSize
, Data
);
1092 return EFI_OUT_OF_RESOURCES
;
1095 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeManualAddress
];
1096 if (DataItem
->Data
.Ptr
!= NULL
) {
1097 FreePool (DataItem
->Data
.Ptr
);
1100 DataItem
->Data
.Ptr
= Ptr
;
1101 DataItem
->DataSize
= DataSize
;
1102 DataItem
->Status
= EFI_NOT_READY
;
1104 StationAddress
= EFI_NTOHL (NewAddress
.Address
);
1105 SubnetMask
= EFI_NTOHL (NewAddress
.SubnetMask
);
1107 Status
= Ip4Config2SetDefaultAddr (Instance
, StationAddress
, SubnetMask
);
1108 if (EFI_ERROR (Status
)) {
1112 DataItem
->Status
= EFI_SUCCESS
;
1115 if (EFI_ERROR (DataItem
->Status
)) {
1119 DataItem
->Data
.Ptr
= NULL
;
1126 The work function is to set the gateway addresses manually for the EFI IPv4
1127 network stack that is running on the communication device that this EFI IPv4
1128 Configuration Protocol manages. It is not configurable when the policy is
1129 Ip4Config2PolicyDhcp. The gateway addresses must be unicast IPv4 addresses.
1131 @param[in] Instance The pointer to the IP4 config2 instance data.
1132 @param[in] DataSize The size of the buffer pointed to by Data in bytes.
1133 @param[in] Data The data buffer to set. This points to an array of
1134 EFI_IPv6_ADDRESS instances.
1136 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
1137 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
1138 under the current policy.
1139 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
1140 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to complete the operation.
1141 @retval EFI_ABORTED The manual gateway addresses to be set equal the
1142 current configuration.
1143 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
1144 network stack was set.
1148 Ip4Config2SetGateway (
1149 IN IP4_CONFIG2_INSTANCE
*Instance
,
1155 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1160 EFI_IPv4_ADDRESS
*OldGateway
;
1161 EFI_IPv4_ADDRESS
*NewGateway
;
1162 UINTN OldGatewayCount
;
1163 UINTN NewGatewayCount
;
1168 if ((DataSize
% sizeof (EFI_IPv4_ADDRESS
) != 0) || (DataSize
== 0)) {
1169 return EFI_BAD_BUFFER_SIZE
;
1172 if (Instance
->Policy
!= Ip4Config2PolicyStatic
) {
1173 return EFI_WRITE_PROTECTED
;
1177 NewGateway
= (EFI_IPv4_ADDRESS
*) Data
;
1178 NewGatewayCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1179 for (Index1
= 0; Index1
< NewGatewayCount
; Index1
++) {
1180 CopyMem (&Gateway
, NewGateway
+ Index1
, sizeof (IP4_ADDR
));
1182 if (!NetIp4IsUnicast (NTOHL (Gateway
), 0)) {
1184 return EFI_INVALID_PARAMETER
;
1187 for (Index2
= Index1
+ 1; Index2
< NewGatewayCount
; Index2
++) {
1188 if (EFI_IP4_EQUAL (NewGateway
+ Index1
, NewGateway
+ Index2
)) {
1189 return EFI_INVALID_PARAMETER
;
1194 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1195 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeGateway
];
1196 OldGateway
= DataItem
->Data
.Gateway
;
1197 OldGatewayCount
= DataItem
->DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1201 if (NewGatewayCount
!= OldGatewayCount
) {
1202 Tmp
= AllocatePool (DataSize
);
1204 return EFI_OUT_OF_RESOURCES
;
1210 for (Index1
= 0; Index1
< OldGatewayCount
; Index1
++) {
1212 // Remove this route entry.
1214 CopyMem (&Gateway
, OldGateway
+ Index1
, sizeof (IP4_ADDR
));
1216 IpSb
->DefaultRouteTable
,
1217 IP4_ALLZERO_ADDRESS
,
1218 IP4_ALLZERO_ADDRESS
,
1225 for (Index1
= 0; Index1
< NewGatewayCount
; Index1
++) {
1226 CopyMem (&Gateway
, NewGateway
+ Index1
, sizeof (IP4_ADDR
));
1228 IpSb
->DefaultRouteTable
,
1229 IP4_ALLZERO_ADDRESS
,
1230 IP4_ALLZERO_ADDRESS
,
1238 if (!OneRemoved
&& !OneAdded
) {
1239 DataItem
->Status
= EFI_SUCCESS
;
1244 if (DataItem
->Data
.Ptr
!= NULL
) {
1245 FreePool (DataItem
->Data
.Ptr
);
1247 DataItem
->Data
.Ptr
= Tmp
;
1250 CopyMem (DataItem
->Data
.Ptr
, Data
, DataSize
);
1251 DataItem
->DataSize
= DataSize
;
1252 DataItem
->Status
= EFI_SUCCESS
;
1259 The work function is to set the DNS server list for the EFI IPv4 network
1260 stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL
1261 manages. It is not configurable when the policy is Ip4Config2PolicyDhcp.
1262 The DNS server addresses must be unicast IPv4 addresses.
1264 @param[in] Instance The pointer to the IP4 config2 instance data.
1265 @param[in] DataSize The size of the buffer pointed to by Data in bytes.
1266 @param[in] Data The data buffer to set, points to an array of
1267 EFI_IPv4_ADDRESS instances.
1269 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
1270 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
1271 under the current policy.
1272 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
1273 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.
1274 @retval EFI_ABORTED The DNS server addresses to be set equal the current
1276 @retval EFI_SUCCESS The specified configuration data for the EFI IPv4
1277 network stack was set.
1281 Ip4Config2SetDnsServer (
1282 IN IP4_CONFIG2_INSTANCE
*Instance
,
1290 EFI_IPv4_ADDRESS
*OldDns
;
1291 EFI_IPv4_ADDRESS
*NewDns
;
1294 IP4_CONFIG2_DATA_ITEM
*Item
;
1297 IP4_ADDR DnsAddress
;
1299 if ((DataSize
% sizeof (EFI_IPv4_ADDRESS
) != 0) || (DataSize
== 0)) {
1300 return EFI_BAD_BUFFER_SIZE
;
1303 if (Instance
->Policy
!= Ip4Config2PolicyStatic
) {
1304 return EFI_WRITE_PROTECTED
;
1307 Item
= &Instance
->DataItem
[Ip4Config2DataTypeDnsServer
];
1308 NewDns
= (EFI_IPv4_ADDRESS
*) Data
;
1309 OldDns
= Item
->Data
.DnsServers
;
1310 NewDnsCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1311 OldDnsCount
= Item
->DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1314 if (NewDnsCount
!= OldDnsCount
) {
1315 Tmp
= AllocatePool (DataSize
);
1317 return EFI_OUT_OF_RESOURCES
;
1323 for (NewIndex
= 0; NewIndex
< NewDnsCount
; NewIndex
++) {
1324 CopyMem (&DnsAddress
, NewDns
+ NewIndex
, sizeof (IP4_ADDR
));
1326 if (!NetIp4IsUnicast (NTOHL (DnsAddress
), 0)) {
1328 // The dns server address must be unicast.
1331 return EFI_INVALID_PARAMETER
;
1334 for (Index1
= NewIndex
+ 1; Index1
< NewDnsCount
; Index1
++) {
1335 if (EFI_IP4_EQUAL (NewDns
+ NewIndex
, NewDns
+ Index1
)) {
1337 return EFI_INVALID_PARAMETER
;
1343 // If any address in the new setting is not in the old settings, skip the
1344 // comparision below.
1349 for (OldIndex
= 0; OldIndex
< OldDnsCount
; OldIndex
++) {
1350 if (EFI_IP4_EQUAL (NewDns
+ NewIndex
, OldDns
+ OldIndex
)) {
1352 // If found break out.
1358 if (OldIndex
== OldDnsCount
) {
1363 if (!OneAdded
&& (DataSize
== Item
->DataSize
)) {
1365 // No new item is added and the size is the same.
1367 Item
->Status
= EFI_SUCCESS
;
1371 if (Item
->Data
.Ptr
!= NULL
) {
1372 FreePool (Item
->Data
.Ptr
);
1374 Item
->Data
.Ptr
= Tmp
;
1377 CopyMem (Item
->Data
.Ptr
, Data
, DataSize
);
1378 Item
->DataSize
= DataSize
;
1379 Item
->Status
= EFI_SUCCESS
;
1386 Generate the operational state of the interface this IP4 config2 instance manages
1387 and output in EFI_IP4_CONFIG2_INTERFACE_INFO.
1389 @param[in] IpSb The pointer to the IP4 service binding instance.
1390 @param[out] IfInfo The pointer to the IP4 config2 interface information structure.
1394 Ip4Config2InitIfInfo (
1395 IN IP4_SERVICE
*IpSb
,
1396 OUT EFI_IP4_CONFIG2_INTERFACE_INFO
*IfInfo
1399 IfInfo
->Name
[0] = L
'e';
1400 IfInfo
->Name
[1] = L
't';
1401 IfInfo
->Name
[2] = L
'h';
1402 IfInfo
->Name
[3] = (CHAR16
) (L
'0' + IpSb
->Ip4Config2Instance
.IfIndex
);
1403 IfInfo
->Name
[4] = 0;
1405 IfInfo
->IfType
= IpSb
->SnpMode
.IfType
;
1406 IfInfo
->HwAddressSize
= IpSb
->SnpMode
.HwAddressSize
;
1407 CopyMem (&IfInfo
->HwAddress
, &IpSb
->SnpMode
.CurrentAddress
, IfInfo
->HwAddressSize
);
1411 The event handle routine when DHCPv4 process is finished or is updated.
1413 @param[in] Event Not used.
1414 @param[in] Context The pointer to the IP4 configuration instance data.
1419 Ip4Config2OnDhcp4Event (
1429 Set the configuration for the EFI IPv4 network stack running on the communication
1430 device this EFI_IP4_CONFIG2_PROTOCOL instance manages.
1432 This function is used to set the configuration data of type DataType for the EFI
1433 IPv4 network stack that is running on the communication device that this EFI IPv4
1434 Configuration Protocol instance manages.
1436 DataSize is used to calculate the count of structure instances in the Data for
1437 a DataType in which multiple structure instances are allowed.
1439 This function is always non-blocking. When setting some type of configuration data,
1440 an asynchronous process is invoked to check the correctness of the data, such as
1441 performing Duplicate Address Detection on the manually set local IPv4 addresses.
1442 EFI_NOT_READY is returned immediately to indicate that such an asynchronous process
1443 is invoked, and the process is not finished yet. The caller wanting to get the result
1444 of the asynchronous process is required to call RegisterDataNotify() to register an
1445 event on the specified configuration data. Once the event is signaled, the caller
1446 can call GetData() to obtain the configuration data and know the result.
1447 For other types of configuration data that do not require an asynchronous configuration
1448 process, the result of the operation is immediately returned.
1450 @param[in] This The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1451 @param[in] DataType The type of data to set.
1452 @param[in] DataSize Size of the buffer pointed to by Data in bytes.
1453 @param[in] Data The data buffer to set. The type of the data buffer is
1454 associated with the DataType.
1456 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
1457 network stack was set successfully.
1458 @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
1461 - One or more fields in Data do not match the requirement of the
1462 data type indicated by DataType.
1463 @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified
1464 configuration data cannot be set under the current policy.
1465 @retval EFI_ACCESS_DENIED Another set operation on the specified configuration
1466 data is already in process.
1467 @retval EFI_NOT_READY An asynchronous process was invoked to set the specified
1468 configuration data, and the process is not finished yet.
1469 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type
1470 indicated by DataType.
1471 @retval EFI_UNSUPPORTED This DataType is not supported.
1472 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
1473 @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.
1478 EfiIp4Config2SetData (
1479 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1480 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1487 IP4_CONFIG2_INSTANCE
*Instance
;
1490 if ((This
== NULL
) || (Data
== NULL
)) {
1491 return EFI_INVALID_PARAMETER
;
1494 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1495 return EFI_UNSUPPORTED
;
1498 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1499 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1500 NET_CHECK_SIGNATURE (IpSb
, IP4_SERVICE_SIGNATURE
);
1503 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1505 Status
= Instance
->DataItem
[DataType
].Status
;
1506 if (Status
!= EFI_NOT_READY
) {
1508 if (Instance
->DataItem
[DataType
].SetData
== NULL
) {
1510 // This type of data is readonly.
1512 Status
= EFI_WRITE_PROTECTED
;
1515 Status
= Instance
->DataItem
[DataType
].SetData (Instance
, DataSize
, Data
);
1516 if (!EFI_ERROR (Status
)) {
1518 // Fire up the events registered with this type of data.
1520 NetMapIterate (&Instance
->DataItem
[DataType
].EventMap
, Ip4Config2SignalEvent
, NULL
);
1521 Ip4Config2WriteConfigData (IpSb
->MacString
, Instance
);
1522 } else if (Status
== EFI_ABORTED
) {
1524 // The SetData is aborted because the data to set is the same with
1525 // the one maintained.
1527 Status
= EFI_SUCCESS
;
1528 NetMapIterate (&Instance
->DataItem
[DataType
].EventMap
, Ip4Config2SignalEvent
, NULL
);
1533 // Another asynchornous process is on the way.
1535 Status
= EFI_ACCESS_DENIED
;
1538 gBS
->RestoreTPL (OldTpl
);
1544 Get the configuration data for the EFI IPv4 network stack running on the communication
1545 device that this EFI_IP4_CONFIG2_PROTOCOL instance manages.
1547 This function returns the configuration data of type DataType for the EFI IPv4 network
1548 stack running on the communication device that this EFI IPv4 Configuration Protocol instance
1551 The caller is responsible for allocating the buffer used to return the specified
1552 configuration data. The required size will be returned to the caller if the size of
1553 the buffer is too small.
1555 EFI_NOT_READY is returned if the specified configuration data is not ready due to an
1556 asynchronous configuration process already in progress. The caller can call RegisterDataNotify()
1557 to register an event on the specified configuration data. Once the asynchronous configuration
1558 process is finished, the event will be signaled, and a subsequent GetData() call will return
1559 the specified configuration data.
1561 @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1562 @param[in] DataType The type of data to get.
1563 @param[in, out] DataSize On input, in bytes, the size of Data. On output, in bytes, the
1564 size of buffer required to store the specified configuration data.
1565 @param[in] Data The data buffer in which the configuration data is returned. The
1566 type of the data buffer is associated with the DataType.
1567 This is an optional parameter that may be NULL.
1569 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
1570 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
1573 - Data is NULL if *DataSize is not zero.
1574 @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data,
1575 and the required size is returned in DataSize.
1576 @retval EFI_NOT_READY The specified configuration data is not ready due to an
1577 asynchronous configuration process already in progress.
1578 @retval EFI_NOT_FOUND The specified configuration data is not found.
1583 EfiIp4Config2GetData (
1584 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1585 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1586 IN OUT UINTN
*DataSize
,
1587 IN VOID
*Data OPTIONAL
1592 IP4_CONFIG2_INSTANCE
*Instance
;
1593 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1595 if ((This
== NULL
) || (DataSize
== NULL
) || ((*DataSize
!= 0) && (Data
== NULL
))) {
1596 return EFI_INVALID_PARAMETER
;
1599 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1600 return EFI_NOT_FOUND
;
1603 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1605 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1606 DataItem
= &Instance
->DataItem
[DataType
];
1608 Status
= Instance
->DataItem
[DataType
].Status
;
1609 if (!EFI_ERROR (Status
)) {
1611 if (DataItem
->GetData
!= NULL
) {
1613 Status
= DataItem
->GetData (Instance
, DataSize
, Data
);
1614 } else if (*DataSize
< Instance
->DataItem
[DataType
].DataSize
) {
1616 // Update the buffer length.
1618 *DataSize
= Instance
->DataItem
[DataType
].DataSize
;
1619 Status
= EFI_BUFFER_TOO_SMALL
;
1622 *DataSize
= Instance
->DataItem
[DataType
].DataSize
;
1623 CopyMem (Data
, Instance
->DataItem
[DataType
].Data
.Ptr
, *DataSize
);
1627 gBS
->RestoreTPL (OldTpl
);
1633 Register an event that is signaled whenever a configuration process on the specified
1634 configuration data is done.
1636 This function registers an event that is to be signaled whenever a configuration
1637 process on the specified configuration data is performed. An event can be registered
1638 for a different DataType simultaneously. The caller is responsible for determining
1639 which type of configuration data causes the signaling of the event in such an event.
1641 @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1642 @param[in] DataType The type of data to unregister the event for.
1643 @param[in] Event The event to register.
1645 @retval EFI_SUCCESS The notification event for the specified configuration data is
1647 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
1648 @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not
1650 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
1651 @retval EFI_ACCESS_DENIED The Event is already registered for the DataType.
1656 EfiIp4Config2RegisterDataNotify (
1657 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1658 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1664 IP4_CONFIG2_INSTANCE
*Instance
;
1668 if ((This
== NULL
) || (Event
== NULL
)) {
1669 return EFI_INVALID_PARAMETER
;
1672 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1673 return EFI_UNSUPPORTED
;
1676 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1678 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1679 EventMap
= &Instance
->DataItem
[DataType
].EventMap
;
1682 // Check whether this event is already registered for this DataType.
1684 Item
= NetMapFindKey (EventMap
, Event
);
1687 Status
= NetMapInsertTail (EventMap
, Event
, NULL
);
1689 if (EFI_ERROR (Status
)) {
1691 Status
= EFI_OUT_OF_RESOURCES
;
1696 Status
= EFI_ACCESS_DENIED
;
1699 gBS
->RestoreTPL (OldTpl
);
1705 Remove a previously registered event for the specified configuration data.
1707 @param This The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1708 @param DataType The type of data to remove from the previously
1710 @param Event The event to be unregistered.
1712 @retval EFI_SUCCESS The event registered for the specified
1713 configuration data was removed.
1714 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
1715 @retval EFI_NOT_FOUND The Event has not been registered for the
1721 EfiIp4Config2UnregisterDataNotify (
1722 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1723 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1729 IP4_CONFIG2_INSTANCE
*Instance
;
1732 if ((This
== NULL
) || (Event
== NULL
)) {
1733 return EFI_INVALID_PARAMETER
;
1736 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1737 return EFI_NOT_FOUND
;
1740 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1742 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1744 Item
= NetMapFindKey (&Instance
->DataItem
[DataType
].EventMap
, Event
);
1747 NetMapRemoveItem (&Instance
->DataItem
[DataType
].EventMap
, Item
, NULL
);
1748 Status
= EFI_SUCCESS
;
1751 Status
= EFI_NOT_FOUND
;
1754 gBS
->RestoreTPL (OldTpl
);
1760 Initialize an IP4_CONFIG2_INSTANCE.
1762 @param[out] Instance The buffer of IP4_CONFIG2_INSTANCE to be initialized.
1764 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.
1765 @retval EFI_SUCCESS The IP4_CONFIG2_INSTANCE initialized successfully.
1769 Ip4Config2InitInstance (
1770 OUT IP4_CONFIG2_INSTANCE
*Instance
1774 IP4_CONFIG2_INSTANCE
*TmpInstance
;
1779 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1782 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1784 Instance
->Signature
= IP4_CONFIG2_INSTANCE_SIGNATURE
;
1788 // Determine the index of this interface.
1791 NET_LIST_FOR_EACH (Entry
, &mIp4Config2InstanceList
) {
1792 TmpInstance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_CONFIG2_INSTANCE
, Link
, IP4_CONFIG2_INSTANCE_SIGNATURE
);
1794 if (TmpInstance
->IfIndex
> IfIndex
) {
1796 // There is a sequence hole because some interface is down.
1804 Instance
->IfIndex
= IfIndex
;
1805 NetListInsertBefore (Entry
, &Instance
->Link
);
1807 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
1809 // Initialize the event map for each data item.
1811 NetMapInit (&Instance
->DataItem
[Index
].EventMap
);
1816 // Initialize each data type: associate storage and set data size for the
1817 // fixed size data types, hook the SetData function, set the data attribute.
1819 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeInterfaceInfo
];
1820 DataItem
->GetData
= Ip4Config2GetIfInfo
;
1821 DataItem
->Data
.Ptr
= &Instance
->InterfaceInfo
;
1822 DataItem
->DataSize
= sizeof (Instance
->InterfaceInfo
);
1823 SET_DATA_ATTRIB (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
| DATA_ATTRIB_VOLATILE
);
1824 Ip4Config2InitIfInfo (IpSb
, &Instance
->InterfaceInfo
);
1826 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypePolicy
];
1827 DataItem
->SetData
= Ip4Config2SetPolicy
;
1828 DataItem
->Data
.Ptr
= &Instance
->Policy
;
1829 DataItem
->DataSize
= sizeof (Instance
->Policy
);
1830 Instance
->Policy
= Ip4Config2PolicyDhcp
;
1831 SET_DATA_ATTRIB (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
);
1833 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeManualAddress
];
1834 DataItem
->SetData
= Ip4Config2SetMaunualAddress
;
1835 DataItem
->Status
= EFI_NOT_FOUND
;
1837 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeGateway
];
1838 DataItem
->SetData
= Ip4Config2SetGateway
;
1839 DataItem
->Status
= EFI_NOT_FOUND
;
1841 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeDnsServer
];
1842 DataItem
->SetData
= Ip4Config2SetDnsServer
;
1843 DataItem
->Status
= EFI_NOT_FOUND
;
1846 // Create the event used for DHCP.
1848 Status
= gBS
->CreateEvent (
1851 Ip4Config2OnDhcp4Event
,
1853 &Instance
->Dhcp4Event
1855 ASSERT_EFI_ERROR (Status
);
1857 Instance
->Configured
= TRUE
;
1860 // Try to read the config data from NV variable.
1862 Status
= Ip4Config2ReadConfigData (IpSb
->MacString
, Instance
);
1863 if (Status
== EFI_NOT_FOUND
) {
1864 Status
= Ip4Config2WriteConfigData (IpSb
->MacString
, Instance
);
1867 if (EFI_ERROR (Status
)) {
1872 // Try to set the configured parameter.
1874 for (Index
= Ip4Config2DataTypePolicy
; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
1875 DataItem
= &IpSb
->Ip4Config2Instance
.DataItem
[Index
];
1876 if (DataItem
->Data
.Ptr
!= NULL
) {
1878 &IpSb
->Ip4Config2Instance
,
1885 Instance
->Ip4Config2
.SetData
= EfiIp4Config2SetData
;
1886 Instance
->Ip4Config2
.GetData
= EfiIp4Config2GetData
;
1887 Instance
->Ip4Config2
.RegisterDataNotify
= EfiIp4Config2RegisterDataNotify
;
1888 Instance
->Ip4Config2
.UnregisterDataNotify
= EfiIp4Config2UnregisterDataNotify
;
1891 // Publish the IP4 configuration form
1893 return Ip4Config2FormInit (Instance
);
1898 Release an IP4_CONFIG2_INSTANCE.
1900 @param[in, out] Instance The buffer of IP4_CONFIG2_INSTANCE to be freed.
1904 Ip4Config2CleanInstance (
1905 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1909 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1911 if (Instance
->DeclineAddress
!= NULL
) {
1912 FreePool (Instance
->DeclineAddress
);
1915 if (!Instance
->Configured
) {
1919 if (Instance
->Dhcp4Handle
!= NULL
) {
1921 Ip4Config2DestroyDhcp4 (Instance
);
1927 if (Instance
->Dhcp4Event
!= NULL
) {
1928 gBS
->CloseEvent (Instance
->Dhcp4Event
);
1931 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
1933 DataItem
= &Instance
->DataItem
[Index
];
1935 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
)) {
1936 if (DataItem
->Data
.Ptr
!= NULL
) {
1937 FreePool (DataItem
->Data
.Ptr
);
1939 DataItem
->Data
.Ptr
= NULL
;
1940 DataItem
->DataSize
= 0;
1943 NetMapClean (&Instance
->DataItem
[Index
].EventMap
);
1946 Ip4Config2FormUnload (Instance
);
1948 RemoveEntryList (&Instance
->Link
);