TianoCore EDK2 master
Loading...
Searching...
No Matches
Ip4Driver.c
Go to the documentation of this file.
1
12#include "Ip4Impl.h"
13
14EFI_DRIVER_BINDING_PROTOCOL gIp4DriverBinding = {
18 0xa,
19 NULL,
20 NULL
21};
22
23BOOLEAN mIpSec2Installed = FALSE;
24
32VOID
33EFIAPI
35 IN EFI_EVENT Event,
36 IN VOID *Context
37 )
38{
39 EFI_STATUS Status;
40
41 //
42 // Test if protocol was even found.
43 // Notification function will be called at least once.
44 //
45 Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **)&mIpSec);
46 if ((Status == EFI_SUCCESS) && (mIpSec != NULL)) {
47 //
48 // Close the event so it does not get called again.
49 //
50 gBS->CloseEvent (Event);
51
52 mIpSec2Installed = TRUE;
53 }
54}
55
72EFIAPI
74 IN EFI_HANDLE ImageHandle,
75 IN EFI_SYSTEM_TABLE *SystemTable
76 )
77{
78 VOID *Registration;
79
81 &gEfiIpSec2ProtocolGuid,
82 TPL_CALLBACK,
84 NULL,
85 &Registration
86 );
87
89 ImageHandle,
90 SystemTable,
91 &gIp4DriverBinding,
92 ImageHandle,
93 &gIp4ComponentName,
94 &gIp4ComponentName2
95 );
96}
97
117EFIAPI
120 IN EFI_HANDLE ControllerHandle,
121 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
122 )
123{
124 EFI_STATUS Status;
125
126 //
127 // Test for the MNP service binding Protocol
128 //
129 Status = gBS->OpenProtocol (
130 ControllerHandle,
131 &gEfiManagedNetworkServiceBindingProtocolGuid,
132 NULL,
133 This->DriverBindingHandle,
134 ControllerHandle,
135 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
136 );
137
138 if (EFI_ERROR (Status)) {
139 return Status;
140 }
141
142 //
143 // Test for the Arp service binding Protocol
144 //
145 Status = gBS->OpenProtocol (
146 ControllerHandle,
147 &gEfiArpServiceBindingProtocolGuid,
148 NULL,
149 This->DriverBindingHandle,
150 ControllerHandle,
151 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
152 );
153
154 return Status;
155}
156
172 IN IP4_SERVICE *IpSb
173 );
174
191 IN EFI_HANDLE Controller,
192 IN EFI_HANDLE ImageHandle,
193 OUT IP4_SERVICE **Service
194 )
195{
196 IP4_SERVICE *IpSb;
197 EFI_STATUS Status;
198
199 ASSERT (Service != NULL);
200
201 *Service = NULL;
202
203 //
204 // allocate a service private data then initialize all the filed to
205 // empty resources, so if any thing goes wrong when allocating
206 // resources, Ip4CleanService can be called to clean it up.
207 //
208 IpSb = AllocateZeroPool (sizeof (IP4_SERVICE));
209
210 if (IpSb == NULL) {
211 return EFI_OUT_OF_RESOURCES;
212 }
213
214 IpSb->Signature = IP4_SERVICE_SIGNATURE;
215 IpSb->ServiceBinding.CreateChild = Ip4ServiceBindingCreateChild;
216 IpSb->ServiceBinding.DestroyChild = Ip4ServiceBindingDestroyChild;
217 IpSb->State = IP4_SERVICE_UNSTARTED;
218
219 IpSb->NumChildren = 0;
220 InitializeListHead (&IpSb->Children);
221
222 InitializeListHead (&IpSb->Interfaces);
223 IpSb->DefaultInterface = NULL;
224 IpSb->DefaultRouteTable = NULL;
225
226 Ip4InitAssembleTable (&IpSb->Assemble);
227
228 IpSb->IgmpCtrl.Igmpv1QuerySeen = 0;
229 InitializeListHead (&IpSb->IgmpCtrl.Groups);
230
231 IpSb->Image = ImageHandle;
232 IpSb->Controller = Controller;
233
234 IpSb->MnpChildHandle = NULL;
235 IpSb->Mnp = NULL;
236
237 IpSb->MnpConfigData.ReceivedQueueTimeoutValue = 0;
238 IpSb->MnpConfigData.TransmitQueueTimeoutValue = 0;
239 IpSb->MnpConfigData.ProtocolTypeFilter = IP4_ETHER_PROTO;
240 IpSb->MnpConfigData.EnableUnicastReceive = TRUE;
241 IpSb->MnpConfigData.EnableMulticastReceive = TRUE;
242 IpSb->MnpConfigData.EnableBroadcastReceive = TRUE;
243 IpSb->MnpConfigData.EnablePromiscuousReceive = FALSE;
244 IpSb->MnpConfigData.FlushQueuesOnReset = TRUE;
245 IpSb->MnpConfigData.EnableReceiveTimestamps = FALSE;
246 IpSb->MnpConfigData.DisableBackgroundPolling = FALSE;
247
248 ZeroMem (&IpSb->SnpMode, sizeof (EFI_SIMPLE_NETWORK_MODE));
249
250 IpSb->Timer = NULL;
251 IpSb->ReconfigCheckTimer = NULL;
252
253 IpSb->ReconfigEvent = NULL;
254
255 IpSb->Reconfig = FALSE;
256
257 IpSb->MediaPresent = TRUE;
258
259 //
260 // Create various resources. First create the route table, timer
261 // event, ReconfigEvent and MNP child. IGMP, interface's initialization depend
262 // on the MNP child.
263 //
264 IpSb->DefaultRouteTable = Ip4CreateRouteTable ();
265
266 if (IpSb->DefaultRouteTable == NULL) {
267 Status = EFI_OUT_OF_RESOURCES;
268 goto ON_ERROR;
269 }
270
271 Status = gBS->CreateEvent (
272 EVT_NOTIFY_SIGNAL | EVT_TIMER,
273 TPL_CALLBACK,
275 IpSb,
276 &IpSb->Timer
277 );
278
279 if (EFI_ERROR (Status)) {
280 goto ON_ERROR;
281 }
282
283 Status = gBS->CreateEvent (
284 EVT_NOTIFY_SIGNAL | EVT_TIMER,
285 TPL_CALLBACK,
287 IpSb,
288 &IpSb->ReconfigCheckTimer
289 );
290
291 if (EFI_ERROR (Status)) {
292 goto ON_ERROR;
293 }
294
295 Status = gBS->CreateEvent (
296 EVT_NOTIFY_SIGNAL,
297 TPL_NOTIFY,
299 IpSb,
300 &IpSb->ReconfigEvent
301 );
302 if (EFI_ERROR (Status)) {
303 goto ON_ERROR;
304 }
305
306 Status = NetLibCreateServiceChild (
307 Controller,
308 ImageHandle,
309 &gEfiManagedNetworkServiceBindingProtocolGuid,
310 &IpSb->MnpChildHandle
311 );
312
313 if (EFI_ERROR (Status)) {
314 goto ON_ERROR;
315 }
316
317 Status = gBS->OpenProtocol (
318 IpSb->MnpChildHandle,
319 &gEfiManagedNetworkProtocolGuid,
320 (VOID **)&IpSb->Mnp,
321 ImageHandle,
322 Controller,
323 EFI_OPEN_PROTOCOL_BY_DRIVER
324 );
325
326 if (EFI_ERROR (Status)) {
327 goto ON_ERROR;
328 }
329
330 Status = Ip4ServiceConfigMnp (IpSb, TRUE);
331
332 if (EFI_ERROR (Status)) {
333 goto ON_ERROR;
334 }
335
336 Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &IpSb->SnpMode);
337
338 if (EFI_ERROR (Status)) {
339 goto ON_ERROR;
340 }
341
342 Status = Ip4InitIgmp (IpSb);
343
344 if (EFI_ERROR (Status)) {
345 goto ON_ERROR;
346 }
347
348 IpSb->MacString = NULL;
349 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &IpSb->MacString);
350
351 if (EFI_ERROR (Status)) {
352 goto ON_ERROR;
353 }
354
355 IpSb->DefaultInterface = Ip4CreateInterface (IpSb->Mnp, Controller, ImageHandle);
356
357 if (IpSb->DefaultInterface == NULL) {
358 Status = EFI_OUT_OF_RESOURCES;
359 goto ON_ERROR;
360 }
361
362 InsertHeadList (&IpSb->Interfaces, &IpSb->DefaultInterface->Link);
363
364 ZeroMem (&IpSb->Ip4Config2Instance, sizeof (IP4_CONFIG2_INSTANCE));
365
366 Status = Ip4Config2InitInstance (&IpSb->Ip4Config2Instance);
367
368 if (EFI_ERROR (Status)) {
369 goto ON_ERROR;
370 }
371
372 IpSb->MaxPacketSize = IpSb->SnpMode.MaxPacketSize - sizeof (IP4_HEAD);
373 if (NetLibGetVlanId (IpSb->Controller) != 0) {
374 //
375 // This is a VLAN device, reduce MTU by VLAN tag length
376 //
377 IpSb->MaxPacketSize -= NET_VLAN_TAG_LEN;
378 }
379
380 IpSb->OldMaxPacketSize = IpSb->MaxPacketSize;
381 *Service = IpSb;
382
383 return EFI_SUCCESS;
384
385ON_ERROR:
386 Ip4CleanService (IpSb);
387 FreePool (IpSb);
388
389 return Status;
390}
391
407 IN IP4_SERVICE *IpSb
408 )
409{
410 EFI_STATUS Status;
411
412 IpSb->State = IP4_SERVICE_DESTROY;
413
414 if (IpSb->Timer != NULL) {
415 gBS->SetTimer (IpSb->Timer, TimerCancel, 0);
416 gBS->CloseEvent (IpSb->Timer);
417
418 IpSb->Timer = NULL;
419 }
420
421 if (IpSb->ReconfigCheckTimer != NULL) {
422 gBS->SetTimer (IpSb->ReconfigCheckTimer, TimerCancel, 0);
423 gBS->CloseEvent (IpSb->ReconfigCheckTimer);
424
425 IpSb->ReconfigCheckTimer = NULL;
426 }
427
428 if (IpSb->DefaultInterface != NULL) {
429 Status = Ip4FreeInterface (IpSb->DefaultInterface, NULL);
430
431 if (EFI_ERROR (Status)) {
432 return Status;
433 }
434
435 IpSb->DefaultInterface = NULL;
436 }
437
438 if (IpSb->DefaultRouteTable != NULL) {
439 Ip4FreeRouteTable (IpSb->DefaultRouteTable);
440 IpSb->DefaultRouteTable = NULL;
441 }
442
443 Ip4CleanAssembleTable (&IpSb->Assemble);
444
445 if (IpSb->MnpChildHandle != NULL) {
446 if (IpSb->Mnp != NULL) {
447 gBS->CloseProtocol (
448 IpSb->MnpChildHandle,
449 &gEfiManagedNetworkProtocolGuid,
450 IpSb->Image,
451 IpSb->Controller
452 );
453
454 IpSb->Mnp = NULL;
455 }
456
458 IpSb->Controller,
459 IpSb->Image,
460 &gEfiManagedNetworkServiceBindingProtocolGuid,
461 IpSb->MnpChildHandle
462 );
463
464 IpSb->MnpChildHandle = NULL;
465 }
466
467 if (IpSb->ReconfigEvent != NULL) {
468 gBS->CloseEvent (IpSb->ReconfigEvent);
469
470 IpSb->ReconfigEvent = NULL;
471 }
472
473 IpSb->Reconfig = FALSE;
474
475 if (IpSb->MacString != NULL) {
476 FreePool (IpSb->MacString);
477 }
478
479 Ip4Config2CleanInstance (&IpSb->Ip4Config2Instance);
480
481 return EFI_SUCCESS;
482}
483
495EFIAPI
497 IN LIST_ENTRY *Entry,
498 IN VOID *Context
499 )
500{
501 IP4_PROTOCOL *IpInstance;
502 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
503 UINTN NumberOfChildren;
504 EFI_HANDLE *ChildHandleBuffer;
505
506 if ((Entry == NULL) || (Context == NULL)) {
507 return EFI_INVALID_PARAMETER;
508 }
509
510 IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, Link, IP4_PROTOCOL_SIGNATURE);
511 ServiceBinding = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
512 NumberOfChildren = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
513 ChildHandleBuffer = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;
514
515 if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
516 return EFI_SUCCESS;
517 }
518
519 return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
520}
521
541EFIAPI
544 IN EFI_HANDLE ControllerHandle,
545 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
546 )
547{
548 EFI_STATUS Status;
549 IP4_SERVICE *IpSb;
551 UINTN Index;
552 IP4_CONFIG2_DATA_ITEM *DataItem;
553 UINT32 Random;
554
555 IpSb = NULL;
556 Ip4Cfg2 = NULL;
557 DataItem = NULL;
558
559 Status = PseudoRandomU32 (&Random);
560 if (EFI_ERROR (Status)) {
561 DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
562 return Status;
563 }
564
565 //
566 // Test for the Ip4 service binding protocol
567 //
568 Status = gBS->OpenProtocol (
569 ControllerHandle,
570 &gEfiIp4ServiceBindingProtocolGuid,
571 NULL,
572 This->DriverBindingHandle,
573 ControllerHandle,
574 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
575 );
576
577 if (Status == EFI_SUCCESS) {
578 return EFI_ALREADY_STARTED;
579 }
580
581 Status = Ip4CreateService (ControllerHandle, This->DriverBindingHandle, &IpSb);
582
583 if (EFI_ERROR (Status)) {
584 return Status;
585 }
586
587 ASSERT (IpSb != NULL);
588
589 Ip4Cfg2 = &IpSb->Ip4Config2Instance.Ip4Config2;
590
591 //
592 // Install the Ip4ServiceBinding Protocol onto ControllerHandle
593 //
594 Status = gBS->InstallMultipleProtocolInterfaces (
595 &ControllerHandle,
596 &gEfiIp4ServiceBindingProtocolGuid,
597 &IpSb->ServiceBinding,
598 &gEfiIp4Config2ProtocolGuid,
599 Ip4Cfg2,
600 NULL
601 );
602
603 if (EFI_ERROR (Status)) {
604 goto FREE_SERVICE;
605 }
606
607 //
608 // Read the config data from NV variable again.
609 // The default data can be changed by other drivers.
610 //
611 Status = Ip4Config2ReadConfigData (IpSb->MacString, &IpSb->Ip4Config2Instance);
612 if (EFI_ERROR (Status)) {
613 goto UNINSTALL_PROTOCOL;
614 }
615
616 //
617 // Consume the installed EFI_IP4_CONFIG2_PROTOCOL to set the default data items.
618 //
619 for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; Index++) {
620 DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];
621 if (DataItem->Data.Ptr != NULL) {
622 Status = Ip4Cfg2->SetData (
623 Ip4Cfg2,
624 Index,
625 DataItem->DataSize,
626 DataItem->Data.Ptr
627 );
628 if (EFI_ERROR (Status)) {
629 goto UNINSTALL_PROTOCOL;
630 }
631
632 if ((Index == Ip4Config2DataTypePolicy) && (*(DataItem->Data.Policy) == Ip4Config2PolicyDhcp)) {
633 break;
634 }
635 }
636 }
637
638 //
639 // Ready to go: start the receiving and timer.
640 // Ip4Config2SetPolicy maybe call Ip4ReceiveFrame() to set the default interface's RecvRequest first after
641 // Ip4Config2 instance is initialized. So, EFI_ALREADY_STARTED is the allowed return status.
642 //
643 Status = Ip4ReceiveFrame (IpSb->DefaultInterface, NULL, Ip4AccpetFrame, IpSb);
644
645 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
646 goto UNINSTALL_PROTOCOL;
647 }
648
649 Status = gBS->SetTimer (IpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);
650
651 if (EFI_ERROR (Status)) {
652 goto UNINSTALL_PROTOCOL;
653 }
654
655 Status = gBS->SetTimer (IpSb->ReconfigCheckTimer, TimerPeriodic, 500 * TICKS_PER_MS);
656
657 if (EFI_ERROR (Status)) {
658 goto UNINSTALL_PROTOCOL;
659 }
660
661 //
662 // Initialize the IP4 ID
663 //
664 mIp4Id = (UINT16)Random;
665
666 return Status;
667
668UNINSTALL_PROTOCOL:
669 gBS->UninstallMultipleProtocolInterfaces (
670 ControllerHandle,
671 &gEfiIp4ServiceBindingProtocolGuid,
672 &IpSb->ServiceBinding,
673 &gEfiIp4Config2ProtocolGuid,
674 Ip4Cfg2,
675 NULL
676 );
677
678FREE_SERVICE:
679 Ip4CleanService (IpSb);
680 FreePool (IpSb);
681 return Status;
682}
683
703EFIAPI
706 IN EFI_HANDLE ControllerHandle,
707 IN UINTN NumberOfChildren,
708 IN EFI_HANDLE *ChildHandleBuffer
709 )
710{
711 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
712 IP4_SERVICE *IpSb;
713 EFI_HANDLE NicHandle;
714 EFI_STATUS Status;
715 INTN State;
716 LIST_ENTRY *List;
718 IP4_INTERFACE *IpIf;
719 IP4_ROUTE_TABLE *RouteTable;
720
721 BOOLEAN IsDhcp4;
722
723 IsDhcp4 = FALSE;
724
725 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
726 if (NicHandle == NULL) {
727 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
728 if (NicHandle == NULL) {
729 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
730 if (NicHandle != NULL) {
731 IsDhcp4 = TRUE;
732 } else {
733 return EFI_SUCCESS;
734 }
735 }
736 }
737
738 Status = gBS->OpenProtocol (
739 NicHandle,
740 &gEfiIp4ServiceBindingProtocolGuid,
741 (VOID **)&ServiceBinding,
742 This->DriverBindingHandle,
743 NicHandle,
744 EFI_OPEN_PROTOCOL_GET_PROTOCOL
745 );
746 if (EFI_ERROR (Status)) {
747 return EFI_DEVICE_ERROR;
748 }
749
750 IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
751
752 if (IsDhcp4) {
753 Status = Ip4Config2DestroyDhcp4 (&IpSb->Ip4Config2Instance);
754 gBS->CloseEvent (IpSb->Ip4Config2Instance.Dhcp4Event);
755 IpSb->Ip4Config2Instance.Dhcp4Event = NULL;
756 } else if (NumberOfChildren != 0) {
757 List = &IpSb->Children;
758 Context.ServiceBinding = ServiceBinding;
759 Context.NumberOfChildren = NumberOfChildren;
760 Context.ChildHandleBuffer = ChildHandleBuffer;
761 Status = NetDestroyLinkList (
762 List,
764 &Context,
765 NULL
766 );
767 } else if (IpSb->DefaultInterface->ArpHandle == ControllerHandle) {
768 //
769 // The ARP protocol for the default interface is being uninstalled and all
770 // its IP child handles should have been destroyed before. So, release the
771 // default interface and route table, create a new one and mark it as not started.
772 //
773 Ip4CancelReceive (IpSb->DefaultInterface);
774 Ip4FreeInterface (IpSb->DefaultInterface, NULL);
775 Ip4FreeRouteTable (IpSb->DefaultRouteTable);
776
777 IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
778 if (IpIf == NULL) {
779 goto ON_ERROR;
780 }
781
782 RouteTable = Ip4CreateRouteTable ();
783 if (RouteTable == NULL) {
784 Ip4FreeInterface (IpIf, NULL);
785 goto ON_ERROR;
786 }
787
788 IpSb->DefaultInterface = IpIf;
789 InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
790 IpSb->DefaultRouteTable = RouteTable;
791 Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
792
793 IpSb->State = IP4_SERVICE_UNSTARTED;
794 } else if (IsListEmpty (&IpSb->Children)) {
795 State = IpSb->State;
796 //
797 // OK, clean other resources then uninstall the service binding protocol.
798 //
799 Status = Ip4CleanService (IpSb);
800 if (EFI_ERROR (Status)) {
801 IpSb->State = State;
802 goto ON_ERROR;
803 }
804
805 gBS->UninstallMultipleProtocolInterfaces (
806 NicHandle,
807 &gEfiIp4ServiceBindingProtocolGuid,
808 ServiceBinding,
809 &gEfiIp4Config2ProtocolGuid,
810 &IpSb->Ip4Config2Instance.Ip4Config2,
811 NULL
812 );
813
814 if (gIp4ControllerNameTable != NULL) {
815 FreeUnicodeStringTable (gIp4ControllerNameTable);
816 gIp4ControllerNameTable = NULL;
817 }
818
819 FreePool (IpSb);
820 }
821
822ON_ERROR:
823 return Status;
824}
825
846EFIAPI
849 IN OUT EFI_HANDLE *ChildHandle
850 )
851{
852 IP4_SERVICE *IpSb;
853 IP4_PROTOCOL *IpInstance;
854 EFI_TPL OldTpl;
855 EFI_STATUS Status;
856 VOID *Mnp;
857
858 if ((This == NULL) || (ChildHandle == NULL)) {
859 return EFI_INVALID_PARAMETER;
860 }
861
862 IpSb = IP4_SERVICE_FROM_PROTOCOL (This);
863 IpInstance = AllocatePool (sizeof (IP4_PROTOCOL));
864
865 if (IpInstance == NULL) {
866 return EFI_OUT_OF_RESOURCES;
867 }
868
869 Ip4InitProtocol (IpSb, IpInstance);
870
871 //
872 // Install Ip4 onto ChildHandle
873 //
874 Status = gBS->InstallMultipleProtocolInterfaces (
875 ChildHandle,
876 &gEfiIp4ProtocolGuid,
877 &IpInstance->Ip4Proto,
878 NULL
879 );
880
881 if (EFI_ERROR (Status)) {
882 goto ON_ERROR;
883 }
884
885 IpInstance->Handle = *ChildHandle;
886
887 //
888 // Open the Managed Network protocol BY_CHILD.
889 //
890 Status = gBS->OpenProtocol (
891 IpSb->MnpChildHandle,
892 &gEfiManagedNetworkProtocolGuid,
893 (VOID **)&Mnp,
894 gIp4DriverBinding.DriverBindingHandle,
895 IpInstance->Handle,
896 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
897 );
898 if (EFI_ERROR (Status)) {
899 gBS->UninstallMultipleProtocolInterfaces (
900 *ChildHandle,
901 &gEfiIp4ProtocolGuid,
902 &IpInstance->Ip4Proto,
903 NULL
904 );
905
906 goto ON_ERROR;
907 }
908
909 //
910 // Insert it into the service binding instance.
911 //
912 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
913
914 InsertTailList (&IpSb->Children, &IpInstance->Link);
915 IpSb->NumChildren++;
916
917 gBS->RestoreTPL (OldTpl);
918
919ON_ERROR:
920
921 if (EFI_ERROR (Status)) {
922 Ip4CleanProtocol (IpInstance);
923
924 FreePool (IpInstance);
925 }
926
927 return Status;
928}
929
949EFIAPI
952 IN EFI_HANDLE ChildHandle
953 )
954{
955 EFI_STATUS Status;
956 IP4_SERVICE *IpSb;
957 IP4_PROTOCOL *IpInstance;
958 EFI_IP4_PROTOCOL *Ip4;
959 EFI_TPL OldTpl;
960
961 if ((This == NULL) || (ChildHandle == NULL)) {
962 return EFI_INVALID_PARAMETER;
963 }
964
965 //
966 // Retrieve the private context data structures
967 //
968 IpSb = IP4_SERVICE_FROM_PROTOCOL (This);
969
970 Status = gBS->OpenProtocol (
971 ChildHandle,
972 &gEfiIp4ProtocolGuid,
973 (VOID **)&Ip4,
974 gIp4DriverBinding.DriverBindingHandle,
975 ChildHandle,
976 EFI_OPEN_PROTOCOL_GET_PROTOCOL
977 );
978
979 if (EFI_ERROR (Status)) {
980 return EFI_UNSUPPORTED;
981 }
982
983 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (Ip4);
984
985 if (IpInstance->Service != IpSb) {
986 return EFI_INVALID_PARAMETER;
987 }
988
989 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
990
991 //
992 // A child can be destroyed more than once. For example,
993 // Ip4DriverBindingStop will destroy all of its children.
994 // when UDP driver is being stopped, it will destroy all
995 // the IP child it opens.
996 //
997 if (IpInstance->InDestroy) {
998 gBS->RestoreTPL (OldTpl);
999 return EFI_SUCCESS;
1000 }
1001
1002 IpInstance->InDestroy = TRUE;
1003
1004 //
1005 // Close the Managed Network protocol.
1006 //
1007 gBS->CloseProtocol (
1008 IpSb->MnpChildHandle,
1009 &gEfiManagedNetworkProtocolGuid,
1010 gIp4DriverBinding.DriverBindingHandle,
1011 ChildHandle
1012 );
1013
1014 if ((IpInstance->Interface != NULL) && (IpInstance->Interface->Arp != NULL)) {
1015 gBS->CloseProtocol (
1016 IpInstance->Interface->ArpHandle,
1017 &gEfiArpProtocolGuid,
1018 gIp4DriverBinding.DriverBindingHandle,
1019 ChildHandle
1020 );
1021 }
1022
1023 //
1024 // Uninstall the IP4 protocol first. Many thing happens during
1025 // this:
1026 // 1. The consumer of the IP4 protocol will be stopped if it
1027 // opens the protocol BY_DRIVER. For example, if MNP driver is
1028 // stopped, IP driver's stop function will be called, and uninstall
1029 // EFI_IP4_PROTOCOL will trigger the UDP's stop function. This
1030 // makes it possible to create the network stack bottom up, and
1031 // stop it top down.
1032 // 2. the upper layer will recycle the received packet. The recycle
1033 // event's TPL is higher than this function. The recycle events
1034 // will be called back before preceding. If any packets not recycled,
1035 // that means there is a resource leak.
1036 //
1037 gBS->RestoreTPL (OldTpl);
1038 Status = gBS->UninstallProtocolInterface (
1039 ChildHandle,
1040 &gEfiIp4ProtocolGuid,
1041 &IpInstance->Ip4Proto
1042 );
1043 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1044 if (EFI_ERROR (Status)) {
1045 IpInstance->InDestroy = FALSE;
1046 goto ON_ERROR;
1047 }
1048
1049 Status = Ip4CleanProtocol (IpInstance);
1050 if (EFI_ERROR (Status)) {
1051 gBS->InstallMultipleProtocolInterfaces (
1052 &ChildHandle,
1053 &gEfiIp4ProtocolGuid,
1054 Ip4,
1055 NULL
1056 );
1057
1058 goto ON_ERROR;
1059 }
1060
1061 RemoveEntryList (&IpInstance->Link);
1062 IpSb->NumChildren--;
1063
1064 gBS->RestoreTPL (OldTpl);
1065
1066 FreePool (IpInstance);
1067 return EFI_SUCCESS;
1068
1069ON_ERROR:
1070 gBS->RestoreTPL (OldTpl);
1071
1072 return Status;
1073}
UINT64 UINTN
INT64 INTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
@ Ip4Config2PolicyDhcp
Definition: Ip4Config2.h:142
@ Ip4Config2DataTypePolicy
Definition: Ip4Config2.h:43
EFI_STATUS Ip4Config2ReadConfigData(IN CHAR16 *VarName, IN OUT IP4_CONFIG2_INSTANCE *Instance)
EFI_STATUS Ip4Config2InitInstance(OUT IP4_CONFIG2_INSTANCE *Instance)
EFI_STATUS Ip4Config2DestroyDhcp4(IN OUT IP4_CONFIG2_INSTANCE *Instance)
VOID Ip4Config2CleanInstance(IN OUT IP4_CONFIG2_INSTANCE *Instance)
VOID EFIAPI Ip4AutoReconfigCallBack(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI Ip4DriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Ip4Driver.c:73
EFI_STATUS EFIAPI Ip4DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: Ip4Driver.c:118
EFI_STATUS Ip4CleanService(IN IP4_SERVICE *IpSb)
Definition: Ip4Driver.c:406
EFI_STATUS EFIAPI Ip4ServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE ChildHandle)
Definition: Ip4Driver.c:950
VOID EFIAPI IpSec2InstalledCallback(IN EFI_EVENT Event, IN VOID *Context)
Definition: Ip4Driver.c:34
EFI_STATUS EFIAPI Ip4DestroyChildEntryInHandleBuffer(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: Ip4Driver.c:496
EFI_STATUS Ip4CreateService(IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle, OUT IP4_SERVICE **Service)
Definition: Ip4Driver.c:190
EFI_STATUS EFIAPI Ip4ServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN OUT EFI_HANDLE *ChildHandle)
Definition: Ip4Driver.c:847
EFI_STATUS EFIAPI Ip4DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: Ip4Driver.c:542
EFI_STATUS EFIAPI Ip4DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: Ip4Driver.c:704
EFI_STATUS Ip4FreeInterface(IN IP4_INTERFACE *Interface, IN IP4_PROTOCOL *IpInstance OPTIONAL)
Definition: Ip4If.c:731
EFI_STATUS Ip4ReceiveFrame(IN IP4_INTERFACE *Interface, IN IP4_PROTOCOL *IpInstance OPTIONAL, IN IP4_FRAME_CALLBACK CallBack, IN VOID *Context)
Definition: Ip4If.c:1303
IP4_INTERFACE * Ip4CreateInterface(IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle)
Definition: Ip4If.c:477
VOID Ip4CancelReceive(IN IP4_INTERFACE *Interface)
Definition: Ip4If.c:699
EFI_STATUS Ip4InitIgmp(IN OUT IP4_SERVICE *IpSb)
Definition: Ip4Igmp.c:29
EFI_STATUS Ip4ServiceConfigMnp(IN IP4_SERVICE *IpSb, IN BOOLEAN Force)
Definition: Ip4Impl.c:465
VOID Ip4InitProtocol(IN IP4_SERVICE *IpSb, IN OUT IP4_PROTOCOL *IpInstance)
Definition: Ip4Impl.c:532
VOID EFIAPI Ip4TimerTicking(IN EFI_EVENT Event, IN VOID *Context)
Definition: Ip4Impl.c:2242
VOID EFIAPI Ip4TimerReconfigChecking(IN EFI_EVENT Event, IN VOID *Context)
Definition: Ip4Impl.c:2270
EFI_STATUS Ip4CleanProtocol(IN IP4_PROTOCOL *IpInstance)
Definition: Ip4Impl.c:760
VOID Ip4CleanAssembleTable(IN IP4_ASSEMBLE_TABLE *Table)
Definition: Ip4Input.c:111
VOID Ip4InitAssembleTable(IN OUT IP4_ASSEMBLE_TABLE *Table)
Definition: Ip4Input.c:92
VOID Ip4AccpetFrame(IN IP4_PROTOCOL *Ip4Instance, IN NET_BUF *Packet, IN EFI_STATUS IoStatus, IN UINT32 Flag, IN VOID *Context)
Definition: Ip4Input.c:838
IP4_ROUTE_TABLE * Ip4CreateRouteTable(VOID)
Definition: Ip4Route.c:177
VOID Ip4FreeRouteTable(IN IP4_ROUTE_TABLE *RtTable)
Definition: Ip4Route.c:211
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI NetLibGetMacString(IN EFI_HANDLE ServiceHandle, IN EFI_HANDLE ImageHandle OPTIONAL, OUT CHAR16 **MacString)
Definition: DxeNetLib.c:2363
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
BOOLEAN EFIAPI NetIsInHandleBuffer(IN EFI_HANDLE Handle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: DxeNetLib.c:1306
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
Definition: DxeNetLib.c:1011
EFI_HANDLE EFIAPI NetLibGetNicHandle(IN EFI_HANDLE Controller, IN EFI_GUID *ProtocolGuid)
Definition: DxeNetLib.c:3019
EFI_STATUS EFIAPI NetDestroyLinkList(IN LIST_ENTRY *List, IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, IN VOID *Context OPTIONAL, OUT UINTN *ListLength OPTIONAL)
Definition: DxeNetLib.c:1236
UINT16 EFIAPI NetLibGetVlanId(IN EFI_HANDLE ServiceHandle)
Definition: DxeNetLib.c:2140
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257
@ TimerCancel
Definition: UefiSpec.h:531
@ TimerPeriodic
Definition: UefiSpec.h:535
UINT32 OldMaxPacketSize
The MTU before IPsec enable.
Definition: Ip4Impl.h:218