TianoCore EDK2 master
Loading...
Searching...
No Matches
Ip4Impl.c
Go to the documentation of this file.
1
8#include "Ip4Impl.h"
9
11
31EFIAPI
34 OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
35 OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
36 OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
37 );
38
83EFIAPI
85 IN EFI_IP4_PROTOCOL *This,
86 IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL
87 );
88
120EFIAPI
122 IN EFI_IP4_PROTOCOL *This,
123 IN BOOLEAN JoinFlag,
124 IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL
125 );
126
178EFIAPI
180 IN EFI_IP4_PROTOCOL *This,
181 IN BOOLEAN DeleteRoute,
182 IN EFI_IPv4_ADDRESS *SubnetAddress,
183 IN EFI_IPv4_ADDRESS *SubnetMask,
184 IN EFI_IPv4_ADDRESS *GatewayAddress
185 );
186
217EFIAPI
219 IN EFI_IP4_PROTOCOL *This,
221 );
222
256EFIAPI
258 IN EFI_IP4_PROTOCOL *This,
260 );
261
292EFIAPI
294 IN EFI_IP4_PROTOCOL *This,
295 IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL
296 );
297
326EFIAPI
328 IN EFI_IP4_PROTOCOL *This
329 );
330
332 mEfiIp4ProtocolTemplete = {
341};
342
362EFIAPI
365 OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
366 OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
367 OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
368 )
369{
370 IP4_PROTOCOL *IpInstance;
371 IP4_SERVICE *IpSb;
372 EFI_IP4_CONFIG_DATA *Config;
373 EFI_STATUS Status;
374 EFI_TPL OldTpl;
375 IP4_ADDR Ip;
376
377 if (This == NULL) {
378 return EFI_INVALID_PARAMETER;
379 }
380
381 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
382 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
383 IpSb = IpInstance->Service;
384
385 if (Ip4ModeData != NULL) {
386 //
387 // IsStarted is "whether the EfiIp4Configure has been called".
388 // IsConfigured is "whether the station address has been configured"
389 //
390 Ip4ModeData->IsStarted = (BOOLEAN)(IpInstance->State == IP4_STATE_CONFIGED);
391 CopyMem (&Ip4ModeData->ConfigData, &IpInstance->ConfigData, sizeof (Ip4ModeData->ConfigData));
392 Ip4ModeData->IsConfigured = FALSE;
393
394 Ip4ModeData->GroupCount = IpInstance->GroupCount;
395 Ip4ModeData->GroupTable = (EFI_IPv4_ADDRESS *)IpInstance->Groups;
396
397 Ip4ModeData->IcmpTypeCount = 23;
398 Ip4ModeData->IcmpTypeList = mIp4SupportedIcmp;
399
400 Ip4ModeData->RouteTable = NULL;
401 Ip4ModeData->RouteCount = 0;
402
403 Ip4ModeData->MaxPacketSize = IpSb->MaxPacketSize;
404
405 //
406 // return the current station address for this IP child. So,
407 // the user can get the default address through this. Some
408 // application wants to know it station address even it is
409 // using the default one, such as a ftp server.
410 //
411 if (Ip4ModeData->IsStarted) {
412 Config = &Ip4ModeData->ConfigData;
413
414 Ip = HTONL (IpInstance->Interface->Ip);
415 CopyMem (&Config->StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
416
417 Ip = HTONL (IpInstance->Interface->SubnetMask);
418 CopyMem (&Config->SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));
419
420 Ip4ModeData->IsConfigured = IpInstance->Interface->Configured;
421
422 //
423 // Build a EFI route table for user from the internal route table.
424 //
425 Status = Ip4BuildEfiRouteTable (IpInstance);
426
427 if (EFI_ERROR (Status)) {
428 gBS->RestoreTPL (OldTpl);
429 return Status;
430 }
431
432 Ip4ModeData->RouteTable = IpInstance->EfiRouteTable;
433 Ip4ModeData->RouteCount = IpInstance->EfiRouteCount;
434 }
435 }
436
437 //
438 // Get fresh mode data from MNP, since underlying media status may change
439 //
440 Status = IpSb->Mnp->GetModeData (IpSb->Mnp, MnpConfigData, SnpModeData);
441
442 gBS->RestoreTPL (OldTpl);
443 return Status;
444}
445
466 IN IP4_SERVICE *IpSb,
467 IN BOOLEAN Force
468 )
469{
470 LIST_ENTRY *Entry;
471 LIST_ENTRY *ProtoEntry;
472 IP4_INTERFACE *IpIf;
473 IP4_PROTOCOL *IpInstance;
474 BOOLEAN Reconfig;
475 BOOLEAN PromiscReceive;
476 EFI_STATUS Status;
477
478 Reconfig = FALSE;
479 PromiscReceive = FALSE;
480
481 if (!Force) {
482 //
483 // Iterate through the IP children to check whether promiscuous
484 // receive setting has been changed. Update the interface's receive
485 // filter also.
486 //
487 NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
488 IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
489 IpIf->PromiscRecv = FALSE;
490
491 NET_LIST_FOR_EACH (ProtoEntry, &IpIf->IpInstances) {
492 IpInstance = NET_LIST_USER_STRUCT (ProtoEntry, IP4_PROTOCOL, AddrLink);
493
494 if (IpInstance->ConfigData.AcceptPromiscuous) {
495 IpIf->PromiscRecv = TRUE;
496 PromiscReceive = TRUE;
497 }
498 }
499 }
500
501 //
502 // If promiscuous receive isn't changed, it isn't necessary to reconfigure.
503 //
504 if (PromiscReceive == IpSb->MnpConfigData.EnablePromiscuousReceive) {
505 return EFI_SUCCESS;
506 }
507
508 Reconfig = TRUE;
509 IpSb->MnpConfigData.EnablePromiscuousReceive = PromiscReceive;
510 }
511
512 Status = IpSb->Mnp->Configure (IpSb->Mnp, &IpSb->MnpConfigData);
513
514 //
515 // recover the original configuration if failed to set the configure.
516 //
517 if (EFI_ERROR (Status) && Reconfig) {
518 IpSb->MnpConfigData.EnablePromiscuousReceive = (BOOLEAN) !PromiscReceive;
519 }
520
521 return Status;
522}
523
531VOID
533 IN IP4_SERVICE *IpSb,
534 IN OUT IP4_PROTOCOL *IpInstance
535 )
536{
537 ASSERT ((IpSb != NULL) && (IpInstance != NULL));
538
539 ZeroMem (IpInstance, sizeof (IP4_PROTOCOL));
540
541 IpInstance->Signature = IP4_PROTOCOL_SIGNATURE;
542 CopyMem (&IpInstance->Ip4Proto, &mEfiIp4ProtocolTemplete, sizeof (IpInstance->Ip4Proto));
543 IpInstance->State = IP4_STATE_UNCONFIGED;
544 IpInstance->InDestroy = FALSE;
545 IpInstance->Service = IpSb;
546
547 InitializeListHead (&IpInstance->Link);
548 NetMapInit (&IpInstance->RxTokens);
549 NetMapInit (&IpInstance->TxTokens);
550 InitializeListHead (&IpInstance->Received);
551 InitializeListHead (&IpInstance->Delivered);
552 InitializeListHead (&IpInstance->AddrLink);
553
554 EfiInitializeLock (&IpInstance->RecycleLock, TPL_NOTIFY);
555}
556
579 IN OUT IP4_PROTOCOL *IpInstance,
580 IN EFI_IP4_CONFIG_DATA *Config
581 )
582{
583 IP4_SERVICE *IpSb;
584 IP4_INTERFACE *IpIf;
585 EFI_STATUS Status;
586 IP4_ADDR Ip;
587 IP4_ADDR Netmask;
588 EFI_ARP_PROTOCOL *Arp;
589 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
591
592 IpSb = IpInstance->Service;
593
594 Ip4Config2 = NULL;
595
596 //
597 // User is changing packet filters. It must be stopped
598 // before the station address can be changed.
599 //
600 if (IpInstance->State == IP4_STATE_CONFIGED) {
601 //
602 // Cancel all the pending transmit/receive from upper layer
603 //
604 Status = Ip4Cancel (IpInstance, NULL);
605
606 if (EFI_ERROR (Status)) {
607 return EFI_DEVICE_ERROR;
608 }
609
610 CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
611 return EFI_SUCCESS;
612 }
613
614 //
615 // Configure a fresh IP4 protocol instance. Create a route table.
616 // Each IP child has its own route table, which may point to the
617 // default table if it is using default address.
618 //
619 Status = EFI_OUT_OF_RESOURCES;
620 IpInstance->RouteTable = Ip4CreateRouteTable ();
621
622 if (IpInstance->RouteTable == NULL) {
623 return Status;
624 }
625
626 //
627 // Set up the interface.
628 //
629 CopyMem (&Ip, &Config->StationAddress, sizeof (IP4_ADDR));
630 CopyMem (&Netmask, &Config->SubnetMask, sizeof (IP4_ADDR));
631
632 Ip = NTOHL (Ip);
633 Netmask = NTOHL (Netmask);
634
635 if (!Config->UseDefaultAddress) {
636 //
637 // Find whether there is already an interface with the same
638 // station address. All the instances with the same station
639 // address shares one interface.
640 //
641 IpIf = Ip4FindStationAddress (IpSb, Ip, Netmask);
642
643 if (IpIf != NULL) {
644 NET_GET_REF (IpIf);
645 } else {
646 IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
647
648 if (IpIf == NULL) {
649 goto ON_ERROR;
650 }
651
652 Status = Ip4SetAddress (IpIf, Ip, Netmask);
653
654 if (EFI_ERROR (Status)) {
655 Status = EFI_DEVICE_ERROR;
656 Ip4FreeInterface (IpIf, IpInstance);
657 goto ON_ERROR;
658 }
659
660 InsertTailList (&IpSb->Interfaces, &IpIf->Link);
661 }
662
663 //
664 // Add a route to this connected network in the instance route table.
665 //
667 IpInstance->RouteTable,
668 Ip & Netmask,
669 Netmask,
670 IP4_ALLZERO_ADDRESS
671 );
672 } else {
673 //
674 // Use the default address. Check the state.
675 //
676 if (IpSb->State == IP4_SERVICE_UNSTARTED) {
677 //
678 // Trigger the EFI_IP4_CONFIG2_PROTOCOL to retrieve the
679 // default IPv4 address if it is not available yet.
680 //
681 Policy = IpSb->Ip4Config2Instance.Policy;
682 if (Policy != Ip4Config2PolicyDhcp) {
683 Ip4Config2 = &IpSb->Ip4Config2Instance.Ip4Config2;
684 Policy = Ip4Config2PolicyDhcp;
685 Status = Ip4Config2->SetData (
686 Ip4Config2,
688 sizeof (EFI_IP4_CONFIG2_POLICY),
689 &Policy
690 );
691 if (EFI_ERROR (Status)) {
692 goto ON_ERROR;
693 }
694 }
695 }
696
697 IpIf = IpSb->DefaultInterface;
698 NET_GET_REF (IpSb->DefaultInterface);
699
700 //
701 // If default address is used, so is the default route table.
702 // Any route set by the instance has the precedence over the
703 // routes in the default route table. Link the default table
704 // after the instance's table. Routing will search the local
705 // table first.
706 //
707 NET_GET_REF (IpSb->DefaultRouteTable);
708 IpInstance->RouteTable->Next = IpSb->DefaultRouteTable;
709 }
710
711 IpInstance->Interface = IpIf;
712 if (IpIf->Arp != NULL) {
713 Arp = NULL;
714 Status = gBS->OpenProtocol (
715 IpIf->ArpHandle,
716 &gEfiArpProtocolGuid,
717 (VOID **)&Arp,
718 gIp4DriverBinding.DriverBindingHandle,
719 IpInstance->Handle,
720 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
721 );
722 if (EFI_ERROR (Status)) {
723 Ip4FreeInterface (IpIf, IpInstance);
724 goto ON_ERROR;
725 }
726 }
727
728 InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
729
730 CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
731 IpInstance->State = IP4_STATE_CONFIGED;
732
733 //
734 // Although EFI_NO_MAPPING is an error code, the IP child has been
735 // successfully configured and doesn't need reconfiguration when
736 // default address is acquired.
737 //
738 if (Config->UseDefaultAddress && IP4_NO_MAPPING (IpInstance)) {
739 return EFI_NO_MAPPING;
740 }
741
742 return EFI_SUCCESS;
743
744ON_ERROR:
745 Ip4FreeRouteTable (IpInstance->RouteTable);
746 IpInstance->RouteTable = NULL;
747 return Status;
748}
749
761 IN IP4_PROTOCOL *IpInstance
762 )
763{
764 if (EFI_ERROR (Ip4Cancel (IpInstance, NULL))) {
765 return EFI_DEVICE_ERROR;
766 }
767
768 if (EFI_ERROR (Ip4Groups (IpInstance, FALSE, NULL))) {
769 return EFI_DEVICE_ERROR;
770 }
771
772 //
773 // Some packets haven't been recycled. It is because either the
774 // user forgets to recycle the packets, or because the callback
775 // hasn't been called. Just leave it alone.
776 //
777 if (!IsListEmpty (&IpInstance->Delivered)) {
778 }
779
780 if (IpInstance->Interface != NULL) {
781 RemoveEntryList (&IpInstance->AddrLink);
782 if (IpInstance->Interface->Arp != NULL) {
783 gBS->CloseProtocol (
784 IpInstance->Interface->ArpHandle,
785 &gEfiArpProtocolGuid,
786 gIp4DriverBinding.DriverBindingHandle,
787 IpInstance->Handle
788 );
789 }
790
791 Ip4FreeInterface (IpInstance->Interface, IpInstance);
792 IpInstance->Interface = NULL;
793 }
794
795 if (IpInstance->RouteTable != NULL) {
796 if (IpInstance->RouteTable->Next != NULL) {
797 Ip4FreeRouteTable (IpInstance->RouteTable->Next);
798 }
799
800 Ip4FreeRouteTable (IpInstance->RouteTable);
801 IpInstance->RouteTable = NULL;
802 }
803
804 if (IpInstance->EfiRouteTable != NULL) {
805 FreePool (IpInstance->EfiRouteTable);
806 IpInstance->EfiRouteTable = NULL;
807 IpInstance->EfiRouteCount = 0;
808 }
809
810 if (IpInstance->Groups != NULL) {
811 FreePool (IpInstance->Groups);
812 IpInstance->Groups = NULL;
813 IpInstance->GroupCount = 0;
814 }
815
816 NetMapClean (&IpInstance->TxTokens);
817
818 NetMapClean (&IpInstance->RxTokens);
819
820 return EFI_SUCCESS;
821}
822
867EFIAPI
869 IN EFI_IP4_PROTOCOL *This,
870 IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL
871 )
872{
873 IP4_PROTOCOL *IpInstance;
874 EFI_IP4_CONFIG_DATA *Current;
875 EFI_TPL OldTpl;
876 EFI_STATUS Status;
877 BOOLEAN AddrOk;
878 IP4_ADDR IpAddress;
879 IP4_ADDR SubnetMask;
880
881 //
882 // First, validate the parameters
883 //
884 if (This == NULL) {
885 return EFI_INVALID_PARAMETER;
886 }
887
888 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
889 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
890
891 //
892 // Validate the configuration first.
893 //
894 if (IpConfigData != NULL) {
895 CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR));
896 CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR));
897
898 IpAddress = NTOHL (IpAddress);
899 SubnetMask = NTOHL (SubnetMask);
900
901 //
902 // Check whether the station address is a valid unicast address
903 //
904 if (!IpConfigData->UseDefaultAddress) {
905 AddrOk = Ip4StationAddressValid (IpAddress, SubnetMask);
906
907 if (!AddrOk) {
908 Status = EFI_INVALID_PARAMETER;
909 goto ON_EXIT;
910 }
911 }
912
913 //
914 // User can only update packet filters when already configured.
915 // If it wants to change the station address, it must configure(NULL)
916 // the instance first.
917 //
918 if (IpInstance->State == IP4_STATE_CONFIGED) {
919 Current = &IpInstance->ConfigData;
920
921 if (Current->UseDefaultAddress != IpConfigData->UseDefaultAddress) {
922 Status = EFI_ALREADY_STARTED;
923 goto ON_EXIT;
924 }
925
926 if (!Current->UseDefaultAddress &&
927 (!EFI_IP4_EQUAL (&Current->StationAddress, &IpConfigData->StationAddress) ||
928 !EFI_IP4_EQUAL (&Current->SubnetMask, &IpConfigData->SubnetMask)))
929 {
930 Status = EFI_ALREADY_STARTED;
931 goto ON_EXIT;
932 }
933
934 if (Current->UseDefaultAddress && IP4_NO_MAPPING (IpInstance)) {
935 Status = EFI_NO_MAPPING;
936 goto ON_EXIT;
937 }
938 }
939 }
940
941 //
942 // Configure the instance or clean it up.
943 //
944 if (IpConfigData != NULL) {
945 Status = Ip4ConfigProtocol (IpInstance, IpConfigData);
946 } else {
947 Status = Ip4CleanProtocol (IpInstance);
948
949 //
950 // Consider the following valid sequence: Mnp is unloaded-->Ip Stopped-->Udp Stopped,
951 // Configure (ThisIp, NULL). If the state is changed to UNCONFIGED,
952 // the unload fails miserably.
953 //
954 if (IpInstance->State == IP4_STATE_CONFIGED) {
955 IpInstance->State = IP4_STATE_UNCONFIGED;
956 }
957 }
958
959 //
960 // Update the MNP's configure data. Ip4ServiceConfigMnp will check
961 // whether it is necessary to reconfigure the MNP.
962 //
963 Ip4ServiceConfigMnp (IpInstance->Service, FALSE);
964
965ON_EXIT:
966 gBS->RestoreTPL (OldTpl);
967 return Status;
968}
969
987 IN IP4_PROTOCOL *IpInstance,
988 IN BOOLEAN JoinFlag,
989 IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL
990 )
991{
992 IP4_ADDR *Members;
993 IP4_ADDR Group;
994 UINT32 Index;
995
996 //
997 // Add it to the instance's Groups, and join the group by IGMP.
998 // IpInstance->Groups is in network byte order. IGMP operates in
999 // host byte order
1000 //
1001 if (JoinFlag) {
1002 //
1003 // When JoinFlag is TRUE, GroupAddress shouldn't be NULL.
1004 //
1005 ASSERT (GroupAddress != NULL);
1006 CopyMem (&Group, GroupAddress, sizeof (IP4_ADDR));
1007
1008 for (Index = 0; Index < IpInstance->GroupCount; Index++) {
1009 if (IpInstance->Groups[Index] == Group) {
1010 return EFI_ALREADY_STARTED;
1011 }
1012 }
1013
1014 Members = Ip4CombineGroups (IpInstance->Groups, IpInstance->GroupCount, Group);
1015
1016 if (Members == NULL) {
1017 return EFI_OUT_OF_RESOURCES;
1018 }
1019
1020 if (EFI_ERROR (Ip4JoinGroup (IpInstance, NTOHL (Group)))) {
1021 FreePool (Members);
1022 return EFI_DEVICE_ERROR;
1023 }
1024
1025 if (IpInstance->Groups != NULL) {
1026 FreePool (IpInstance->Groups);
1027 }
1028
1029 IpInstance->Groups = Members;
1030 IpInstance->GroupCount++;
1031
1032 return EFI_SUCCESS;
1033 }
1034
1035 //
1036 // Leave the group. Leave all the groups if GroupAddress is NULL.
1037 // Must iterate from the end to the beginning because the GroupCount
1038 // is decremented each time an address is removed..
1039 //
1040 for (Index = IpInstance->GroupCount; Index > 0; Index--) {
1041 ASSERT (IpInstance->Groups != NULL);
1042 Group = IpInstance->Groups[Index - 1];
1043 if ((GroupAddress == NULL) || EFI_IP4_EQUAL (&Group, GroupAddress)) {
1044 if (EFI_ERROR (Ip4LeaveGroup (IpInstance, NTOHL (Group)))) {
1045 return EFI_DEVICE_ERROR;
1046 }
1047
1048 Ip4RemoveGroupAddr (IpInstance->Groups, IpInstance->GroupCount, Group);
1049 IpInstance->GroupCount--;
1050
1051 if (IpInstance->GroupCount == 0) {
1052 ASSERT (Index == 1);
1053
1054 FreePool (IpInstance->Groups);
1055 IpInstance->Groups = NULL;
1056 }
1057
1058 if (GroupAddress != NULL) {
1059 return EFI_SUCCESS;
1060 }
1061 }
1062 }
1063
1064 return ((GroupAddress != NULL) ? EFI_NOT_FOUND : EFI_SUCCESS);
1065}
1066
1098EFIAPI
1100 IN EFI_IP4_PROTOCOL *This,
1101 IN BOOLEAN JoinFlag,
1102 IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL
1103 )
1104{
1105 IP4_PROTOCOL *IpInstance;
1106 EFI_STATUS Status;
1107 EFI_TPL OldTpl;
1108 IP4_ADDR McastIp;
1109
1110 if ((This == NULL) || (JoinFlag && (GroupAddress == NULL))) {
1111 return EFI_INVALID_PARAMETER;
1112 }
1113
1114 if (GroupAddress != NULL) {
1115 CopyMem (&McastIp, GroupAddress, sizeof (IP4_ADDR));
1116
1117 if (!IP4_IS_MULTICAST (NTOHL (McastIp))) {
1118 return EFI_INVALID_PARAMETER;
1119 }
1120 }
1121
1122 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
1123 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1124
1125 if (IpInstance->State != IP4_STATE_CONFIGED) {
1126 Status = EFI_NOT_STARTED;
1127 goto ON_EXIT;
1128 }
1129
1130 if (IpInstance->ConfigData.UseDefaultAddress && IP4_NO_MAPPING (IpInstance)) {
1131 Status = EFI_NO_MAPPING;
1132 goto ON_EXIT;
1133 }
1134
1135 Status = Ip4Groups (IpInstance, JoinFlag, GroupAddress);
1136
1137ON_EXIT:
1138 gBS->RestoreTPL (OldTpl);
1139 return Status;
1140}
1141
1193EFIAPI
1195 IN EFI_IP4_PROTOCOL *This,
1196 IN BOOLEAN DeleteRoute,
1197 IN EFI_IPv4_ADDRESS *SubnetAddress,
1198 IN EFI_IPv4_ADDRESS *SubnetMask,
1199 IN EFI_IPv4_ADDRESS *GatewayAddress
1200 )
1201{
1202 IP4_PROTOCOL *IpInstance;
1203 IP4_INTERFACE *IpIf;
1204 IP4_ADDR Dest;
1205 IP4_ADDR Netmask;
1206 IP4_ADDR Nexthop;
1207 EFI_STATUS Status;
1208 EFI_TPL OldTpl;
1209
1210 //
1211 // First, validate the parameters
1212 //
1213 if ((This == NULL) || (SubnetAddress == NULL) ||
1214 (SubnetMask == NULL) || (GatewayAddress == NULL))
1215 {
1216 return EFI_INVALID_PARAMETER;
1217 }
1218
1219 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
1220 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1221
1222 if (IpInstance->State != IP4_STATE_CONFIGED) {
1223 Status = EFI_NOT_STARTED;
1224 goto ON_EXIT;
1225 }
1226
1227 if (IpInstance->ConfigData.UseDefaultAddress && IP4_NO_MAPPING (IpInstance)) {
1228 Status = EFI_NO_MAPPING;
1229 goto ON_EXIT;
1230 }
1231
1232 CopyMem (&Dest, SubnetAddress, sizeof (IP4_ADDR));
1233 CopyMem (&Netmask, SubnetMask, sizeof (IP4_ADDR));
1234 CopyMem (&Nexthop, GatewayAddress, sizeof (IP4_ADDR));
1235
1236 Dest = NTOHL (Dest);
1237 Netmask = NTOHL (Netmask);
1238 Nexthop = NTOHL (Nexthop);
1239
1240 IpIf = IpInstance->Interface;
1241
1242 if (!IP4_IS_VALID_NETMASK (Netmask)) {
1243 Status = EFI_INVALID_PARAMETER;
1244 goto ON_EXIT;
1245 }
1246
1247 //
1248 // the gateway address must be a unicast on the connected network if not zero.
1249 //
1250 if ((Nexthop != IP4_ALLZERO_ADDRESS) &&
1251 (((IpIf->SubnetMask != IP4_ALLONE_ADDRESS) && !IP4_NET_EQUAL (Nexthop, IpIf->Ip, IpIf->SubnetMask)) ||
1252 IP4_IS_BROADCAST (Ip4GetNetCast (Nexthop, IpIf))))
1253 {
1254 Status = EFI_INVALID_PARAMETER;
1255 goto ON_EXIT;
1256 }
1257
1258 if (DeleteRoute) {
1259 Status = Ip4DelRoute (IpInstance->RouteTable, Dest, Netmask, Nexthop);
1260 } else {
1261 Status = Ip4AddRoute (IpInstance->RouteTable, Dest, Netmask, Nexthop);
1262 }
1263
1264ON_EXIT:
1265 gBS->RestoreTPL (OldTpl);
1266 return Status;
1267}
1268
1284EFIAPI
1286 IN NET_MAP *Map,
1287 IN NET_MAP_ITEM *Item,
1288 IN VOID *Context
1289 )
1290{
1292 EFI_IP4_COMPLETION_TOKEN *TokenInItem;
1293
1294 Token = (EFI_IP4_COMPLETION_TOKEN *)Context;
1295 TokenInItem = (EFI_IP4_COMPLETION_TOKEN *)Item->Key;
1296
1297 if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
1298 return EFI_ACCESS_DENIED;
1299 }
1300
1301 return EFI_SUCCESS;
1302}
1303
1319 IN IP4_INTERFACE *IpIf,
1320 IN BOOLEAN RawData
1321 )
1322{
1323 EFI_IP4_TRANSMIT_DATA *TxData;
1324 EFI_IP4_OVERRIDE_DATA *Override;
1325 IP4_ADDR Src;
1326 IP4_ADDR Gateway;
1327 UINT32 Offset;
1328 UINT32 Index;
1329 UINT32 HeadLen;
1330
1331 if ((Token == NULL) || (Token->Event == NULL) || (Token->Packet.TxData == NULL)) {
1332 return EFI_INVALID_PARAMETER;
1333 }
1334
1335 TxData = Token->Packet.TxData;
1336
1337 //
1338 // Check the fragment table: no empty fragment, and length isn't bogus.
1339 //
1340 if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) {
1341 return EFI_INVALID_PARAMETER;
1342 }
1343
1344 Offset = TxData->TotalDataLength;
1345
1346 if (Offset > IP4_MAX_PACKET_SIZE) {
1347 return EFI_BAD_BUFFER_SIZE;
1348 }
1349
1350 for (Index = 0; Index < TxData->FragmentCount; Index++) {
1351 if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||
1352 (TxData->FragmentTable[Index].FragmentLength == 0))
1353 {
1354 return EFI_INVALID_PARAMETER;
1355 }
1356
1357 Offset -= TxData->FragmentTable[Index].FragmentLength;
1358 }
1359
1360 if (Offset != 0) {
1361 return EFI_INVALID_PARAMETER;
1362 }
1363
1364 //
1365 // NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData
1366 // is TRUE.
1367 //
1368 if (RawData) {
1369 return EFI_SUCCESS;
1370 }
1371
1372 //
1373 // Check the IP options: no more than 40 bytes and format is OK
1374 //
1375 if (TxData->OptionsLength != 0) {
1376 if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
1377 return EFI_INVALID_PARAMETER;
1378 }
1379
1380 if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
1381 return EFI_INVALID_PARAMETER;
1382 }
1383 }
1384
1385 //
1386 // Check the source and gateway: they must be a valid unicast.
1387 // Gateway must also be on the connected network.
1388 //
1389 if (TxData->OverrideData != NULL) {
1390 Override = TxData->OverrideData;
1391
1392 CopyMem (&Src, &Override->SourceAddress, sizeof (IP4_ADDR));
1393 CopyMem (&Gateway, &Override->GatewayAddress, sizeof (IP4_ADDR));
1394
1395 Src = NTOHL (Src);
1396 Gateway = NTOHL (Gateway);
1397
1398 if ((NetGetIpClass (Src) > IP4_ADDR_CLASSC) ||
1399 (Src == IP4_ALLONE_ADDRESS) ||
1400 IP4_IS_BROADCAST (Ip4GetNetCast (Src, IpIf)))
1401 {
1402 return EFI_INVALID_PARAMETER;
1403 }
1404
1405 //
1406 // If gateway isn't zero, it must be a unicast address, and
1407 // on the connected network.
1408 //
1409 if ((Gateway != IP4_ALLZERO_ADDRESS) &&
1410 ((NetGetIpClass (Gateway) > IP4_ADDR_CLASSC) ||
1411 !IP4_NET_EQUAL (Gateway, IpIf->Ip, IpIf->SubnetMask) ||
1412 IP4_IS_BROADCAST (Ip4GetNetCast (Gateway, IpIf))))
1413 {
1414 return EFI_INVALID_PARAMETER;
1415 }
1416 }
1417
1418 //
1419 // Check the packet length: Head length and packet length all has a limit
1420 //
1421 HeadLen = sizeof (IP4_HEAD) + ((TxData->OptionsLength + 3) &~0x03);
1422
1423 if ((HeadLen > IP4_MAX_HEADLEN) ||
1424 (TxData->TotalDataLength + HeadLen > IP4_MAX_PACKET_SIZE))
1425 {
1426 return EFI_BAD_BUFFER_SIZE;
1427 }
1428
1429 return EFI_SUCCESS;
1430}
1431
1453VOID
1454EFIAPI
1456 IN VOID *Context
1457 )
1458{
1459 IP4_TXTOKEN_WRAP *Wrap;
1460 NET_MAP_ITEM *Item;
1461
1462 Wrap = (IP4_TXTOKEN_WRAP *)Context;
1463
1464 //
1465 // Signal IpSecRecycleEvent to inform IPsec free the memory
1466 //
1467 if (Wrap->IpSecRecycleSignal != NULL) {
1468 gBS->SignalEvent (Wrap->IpSecRecycleSignal);
1469 }
1470
1471 //
1472 // Find the token in the instance's map. EfiIp4Transmit put the
1473 // token to the map. If that failed, NetMapFindKey will return NULL.
1474 //
1475 Item = NetMapFindKey (&Wrap->IpInstance->TxTokens, Wrap->Token);
1476
1477 if (Item != NULL) {
1478 NetMapRemoveItem (&Wrap->IpInstance->TxTokens, Item, NULL);
1479 }
1480
1481 if (Wrap->Sent) {
1482 gBS->SignalEvent (Wrap->Token->Event);
1483
1484 //
1485 // Dispatch the DPC queued by the NotifyFunction of Token->Event.
1486 //
1487 DispatchDpc ();
1488 }
1489
1490 FreePool (Wrap);
1491}
1492
1503VOID
1505 IP4_PROTOCOL *Ip4Instance,
1506 NET_BUF *Packet,
1507 EFI_STATUS IoStatus,
1508 UINT32 Flag,
1509 VOID *Context
1510 )
1511{
1512 IP4_TXTOKEN_WRAP *Wrap;
1513
1514 //
1515 // This is the transmission request from upper layer,
1516 // not the IP4 driver itself.
1517 //
1518 ASSERT (Ip4Instance != NULL);
1519
1520 //
1521 // The first fragment of the packet has been sent. Update
1522 // the token's status. That is, if fragmented, the transmit's
1523 // status is the first fragment's status. The Wrap will be
1524 // release when all the fragments are release. Check the comments
1525 // in Ip4FreeTxToken and Ip4Output for information.
1526 //
1527 Wrap = (IP4_TXTOKEN_WRAP *)Context;
1528 Wrap->Token->Status = IoStatus;
1529
1530 NetbufFree (Wrap->Packet);
1531}
1532
1563EFIAPI
1565 IN EFI_IP4_PROTOCOL *This,
1567 )
1568{
1569 IP4_SERVICE *IpSb;
1570 IP4_PROTOCOL *IpInstance;
1571 IP4_INTERFACE *IpIf;
1572 IP4_TXTOKEN_WRAP *Wrap;
1573 EFI_IP4_TRANSMIT_DATA *TxData;
1574 EFI_IP4_CONFIG_DATA *Config;
1575 EFI_IP4_OVERRIDE_DATA *Override;
1576 IP4_HEAD Head;
1577 IP4_ADDR GateWay;
1578 EFI_STATUS Status;
1579 EFI_TPL OldTpl;
1580 BOOLEAN DontFragment;
1581 UINT32 HeadLen;
1582 UINT8 RawHdrLen;
1583 UINT32 OptionsLength;
1584 UINT8 *OptionsBuffer;
1585 VOID *FirstFragment;
1586
1587 if (This == NULL) {
1588 return EFI_INVALID_PARAMETER;
1589 }
1590
1591 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
1592
1593 if (IpInstance->State != IP4_STATE_CONFIGED) {
1594 return EFI_NOT_STARTED;
1595 }
1596
1597 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1598
1599 IpSb = IpInstance->Service;
1600 IpIf = IpInstance->Interface;
1601 Config = &IpInstance->ConfigData;
1602
1603 if (Config->UseDefaultAddress && IP4_NO_MAPPING (IpInstance)) {
1604 Status = EFI_NO_MAPPING;
1605 goto ON_EXIT;
1606 }
1607
1608 //
1609 // make sure that token is properly formatted
1610 //
1611 Status = Ip4TxTokenValid (Token, IpIf, Config->RawData);
1612
1613 if (EFI_ERROR (Status)) {
1614 goto ON_EXIT;
1615 }
1616
1617 //
1618 // Check whether the token or signal already existed.
1619 //
1620 if (EFI_ERROR (NetMapIterate (&IpInstance->TxTokens, Ip4TokenExist, Token))) {
1621 Status = EFI_ACCESS_DENIED;
1622 goto ON_EXIT;
1623 }
1624
1625 //
1626 // Build the IP header, need to fill in the Tos, TotalLen, Id,
1627 // fragment, Ttl, protocol, Src, and Dst.
1628 //
1629 TxData = Token->Packet.TxData;
1630
1631 FirstFragment = NULL;
1632
1633 if (Config->RawData) {
1634 //
1635 // When RawData is TRUE, first buffer in FragmentTable points to a raw
1636 // IPv4 fragment including IPv4 header and options.
1637 //
1638 FirstFragment = TxData->FragmentTable[0].FragmentBuffer;
1639 CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8));
1640
1641 RawHdrLen = (UINT8)(RawHdrLen & 0x0f);
1642 if (RawHdrLen < 5) {
1643 Status = EFI_INVALID_PARAMETER;
1644 goto ON_EXIT;
1645 }
1646
1647 RawHdrLen = (UINT8)(RawHdrLen << 2);
1648
1649 CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);
1650
1651 Ip4NtohHead (&Head);
1652 HeadLen = 0;
1653 DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);
1654
1655 if (!DontFragment) {
1656 Status = EFI_INVALID_PARAMETER;
1657 goto ON_EXIT;
1658 }
1659
1660 GateWay = IP4_ALLZERO_ADDRESS;
1661
1662 //
1663 // Get IPv4 options from first fragment.
1664 //
1665 if (RawHdrLen == IP4_MIN_HEADLEN) {
1666 OptionsLength = 0;
1667 OptionsBuffer = NULL;
1668 } else {
1669 OptionsLength = RawHdrLen - IP4_MIN_HEADLEN;
1670 OptionsBuffer = (UINT8 *)FirstFragment + IP4_MIN_HEADLEN;
1671 }
1672
1673 //
1674 // Trim off IPv4 header and options from first fragment.
1675 //
1676 TxData->FragmentTable[0].FragmentBuffer = (UINT8 *)FirstFragment + RawHdrLen;
1677 TxData->FragmentTable[0].FragmentLength = TxData->FragmentTable[0].FragmentLength - RawHdrLen;
1678 } else {
1679 CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
1680 Head.Dst = NTOHL (Head.Dst);
1681
1682 if (TxData->OverrideData != NULL) {
1683 Override = TxData->OverrideData;
1684 Head.Protocol = Override->Protocol;
1685 Head.Tos = Override->TypeOfService;
1686 Head.Ttl = Override->TimeToLive;
1687 DontFragment = Override->DoNotFragment;
1688
1689 CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
1690 CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
1691
1692 Head.Src = NTOHL (Head.Src);
1693 GateWay = NTOHL (GateWay);
1694 } else {
1695 Head.Src = IpIf->Ip;
1696 GateWay = IP4_ALLZERO_ADDRESS;
1697 Head.Protocol = Config->DefaultProtocol;
1698 Head.Tos = Config->TypeOfService;
1699 Head.Ttl = Config->TimeToLive;
1700 DontFragment = Config->DoNotFragment;
1701 }
1702
1703 Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
1704 HeadLen = (TxData->OptionsLength + 3) & (~0x03);
1705
1706 OptionsLength = TxData->OptionsLength;
1707 OptionsBuffer = (UINT8 *)(TxData->OptionsBuffer);
1708 }
1709
1710 //
1711 // If don't fragment and fragment needed, return error
1712 //
1713 if (DontFragment && (TxData->TotalDataLength + HeadLen > IpSb->MaxPacketSize)) {
1714 Status = EFI_BAD_BUFFER_SIZE;
1715 goto ON_EXIT;
1716 }
1717
1718 //
1719 // OK, it survives all the validation check. Wrap the token in
1720 // a IP4_TXTOKEN_WRAP and the data in a netbuf
1721 //
1722 Status = EFI_OUT_OF_RESOURCES;
1723 Wrap = AllocateZeroPool (sizeof (IP4_TXTOKEN_WRAP));
1724 if (Wrap == NULL) {
1725 goto ON_EXIT;
1726 }
1727
1728 Wrap->IpInstance = IpInstance;
1729 Wrap->Token = Token;
1730 Wrap->Sent = FALSE;
1731 Wrap->Life = IP4_US_TO_SEC (Config->TransmitTimeout);
1732 Wrap->Packet = NetbufFromExt (
1733 (NET_FRAGMENT *)TxData->FragmentTable,
1734 TxData->FragmentCount,
1735 IP4_MAX_HEADLEN,
1736 0,
1738 Wrap
1739 );
1740
1741 if (Wrap->Packet == NULL) {
1742 FreePool (Wrap);
1743 goto ON_EXIT;
1744 }
1745
1746 Token->Status = EFI_NOT_READY;
1747
1748 if (EFI_ERROR (NetMapInsertTail (&IpInstance->TxTokens, Token, Wrap))) {
1749 //
1750 // NetbufFree will call Ip4FreeTxToken, which in turn will
1751 // free the IP4_TXTOKEN_WRAP. Now, the token wrap hasn't been
1752 // enqueued.
1753 //
1754 if (Config->RawData) {
1755 //
1756 // Restore pointer of first fragment in RawData mode.
1757 //
1758 TxData->FragmentTable[0].FragmentBuffer = (UINT8 *)FirstFragment;
1759 }
1760
1761 NetbufFree (Wrap->Packet);
1762 goto ON_EXIT;
1763 }
1764
1765 //
1766 // Mark the packet sent before output it. Mark it not sent again if the
1767 // returned status is not EFI_SUCCESS;
1768 //
1769 Wrap->Sent = TRUE;
1770
1771 Status = Ip4Output (
1772 IpSb,
1773 IpInstance,
1774 Wrap->Packet,
1775 &Head,
1776 OptionsBuffer,
1777 OptionsLength,
1778 GateWay,
1780 Wrap
1781 );
1782
1783 if (EFI_ERROR (Status)) {
1784 Wrap->Sent = FALSE;
1785
1786 if (Config->RawData) {
1787 //
1788 // Restore pointer of first fragment in RawData mode.
1789 //
1790 TxData->FragmentTable[0].FragmentBuffer = (UINT8 *)FirstFragment;
1791 }
1792
1793 NetbufFree (Wrap->Packet);
1794 }
1795
1796 if (Config->RawData) {
1797 //
1798 // Restore pointer of first fragment in RawData mode.
1799 //
1800 TxData->FragmentTable[0].FragmentBuffer = (UINT8 *)FirstFragment;
1801 }
1802
1803ON_EXIT:
1804 gBS->RestoreTPL (OldTpl);
1805 return Status;
1806}
1807
1841EFIAPI
1843 IN EFI_IP4_PROTOCOL *This,
1845 )
1846{
1847 IP4_PROTOCOL *IpInstance;
1848 EFI_STATUS Status;
1849 EFI_TPL OldTpl;
1850
1851 //
1852 // First validate the parameters
1853 //
1854 if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
1855 return EFI_INVALID_PARAMETER;
1856 }
1857
1858 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
1859
1860 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1861
1862 if (IpInstance->State != IP4_STATE_CONFIGED) {
1863 Status = EFI_NOT_STARTED;
1864 goto ON_EXIT;
1865 }
1866
1867 //
1868 // Check whether the toke is already on the receive queue.
1869 //
1870 Status = NetMapIterate (&IpInstance->RxTokens, Ip4TokenExist, Token);
1871
1872 if (EFI_ERROR (Status)) {
1873 Status = EFI_ACCESS_DENIED;
1874 goto ON_EXIT;
1875 }
1876
1877 //
1878 // Queue the token then check whether there is pending received packet.
1879 //
1880 Status = NetMapInsertTail (&IpInstance->RxTokens, Token, NULL);
1881
1882 if (EFI_ERROR (Status)) {
1883 goto ON_EXIT;
1884 }
1885
1886 Status = Ip4InstanceDeliverPacket (IpInstance);
1887
1888 //
1889 // Dispatch the DPC queued by the NotifyFunction of this instane's receive
1890 // event.
1891 //
1892 DispatchDpc ();
1893
1894ON_EXIT:
1895 gBS->RestoreTPL (OldTpl);
1896 return Status;
1897}
1898
1917EFIAPI
1919 IN NET_MAP *Map,
1920 IN NET_MAP_ITEM *Item,
1921 IN VOID *Context
1922 )
1923{
1925 IP4_TXTOKEN_WRAP *Wrap;
1926
1927 Token = (EFI_IP4_COMPLETION_TOKEN *)Context;
1928
1929 //
1930 // Return EFI_SUCCESS to check the next item in the map if
1931 // this one doesn't match.
1932 //
1933 if ((Token != NULL) && (Token != Item->Key)) {
1934 return EFI_SUCCESS;
1935 }
1936
1937 Wrap = (IP4_TXTOKEN_WRAP *)Item->Value;
1938 ASSERT (Wrap != NULL);
1939
1940 //
1941 // Don't access the Item, Wrap and Token's members after this point.
1942 // Item and wrap has been freed. And we no longer own the Token.
1943 //
1944 Ip4CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED);
1945
1946 //
1947 // If only one item is to be cancel, return EFI_ABORTED to stop
1948 // iterating the map any more.
1949 //
1950 if (Token != NULL) {
1951 return EFI_ABORTED;
1952 }
1953
1954 return EFI_SUCCESS;
1955}
1956
1972EFIAPI
1974 IN NET_MAP *Map,
1975 IN NET_MAP_ITEM *Item,
1976 IN VOID *Context
1977 )
1978{
1981
1982 Token = (EFI_IP4_COMPLETION_TOKEN *)Context;
1983 This = Item->Key;
1984
1985 if ((Token != NULL) && (Token != This)) {
1986 return EFI_SUCCESS;
1987 }
1988
1989 NetMapRemoveItem (Map, Item, NULL);
1990
1991 This->Status = EFI_ABORTED;
1992 This->Packet.RxData = NULL;
1993 gBS->SignalEvent (This->Event);
1994
1995 if (Token != NULL) {
1996 return EFI_ABORTED;
1997 }
1998
1999 return EFI_SUCCESS;
2000}
2001
2017 IN IP4_PROTOCOL *IpInstance,
2018 IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL
2019 )
2020{
2021 EFI_STATUS Status;
2022
2023 //
2024 // First check the transmitted packet. Ip4CancelTxTokens returns
2025 // EFI_ABORTED to mean that the token has been cancelled when
2026 // token != NULL. So, return EFI_SUCCESS for this condition.
2027 //
2028 Status = NetMapIterate (&IpInstance->TxTokens, Ip4CancelTxTokens, Token);
2029
2030 if (EFI_ERROR (Status)) {
2031 if ((Token != NULL) && (Status == EFI_ABORTED)) {
2032 return EFI_SUCCESS;
2033 }
2034
2035 return Status;
2036 }
2037
2038 //
2039 // Check the receive queue. Ip4CancelRxTokens also returns EFI_ABORT
2040 // for Token!=NULL and it is cancelled.
2041 //
2042 Status = NetMapIterate (&IpInstance->RxTokens, Ip4CancelRxTokens, Token);
2043 //
2044 // Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's
2045 // events.
2046 //
2047 DispatchDpc ();
2048 if (EFI_ERROR (Status)) {
2049 if ((Token != NULL) && (Status == EFI_ABORTED)) {
2050 return EFI_SUCCESS;
2051 }
2052
2053 return Status;
2054 }
2055
2056 //
2057 // OK, if the Token is found when Token != NULL, the NetMapIterate
2058 // will return EFI_ABORTED, which has been interrupted as EFI_SUCCESS.
2059 //
2060 if (Token != NULL) {
2061 return EFI_NOT_FOUND;
2062 }
2063
2064 //
2065 // If Token == NULL, cancel all the tokens. return error if no
2066 // all of them are cancelled.
2067 //
2068 if (!NetMapIsEmpty (&IpInstance->TxTokens) ||
2069 !NetMapIsEmpty (&IpInstance->RxTokens))
2070 {
2071 return EFI_DEVICE_ERROR;
2072 }
2073
2074 return EFI_SUCCESS;
2075}
2076
2107EFIAPI
2109 IN EFI_IP4_PROTOCOL *This,
2110 IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL
2111 )
2112{
2113 IP4_PROTOCOL *IpInstance;
2114 EFI_STATUS Status;
2115 EFI_TPL OldTpl;
2116
2117 if (This == NULL) {
2118 return EFI_INVALID_PARAMETER;
2119 }
2120
2121 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
2122
2123 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
2124
2125 if (IpInstance->State != IP4_STATE_CONFIGED) {
2126 Status = EFI_NOT_STARTED;
2127 goto ON_EXIT;
2128 }
2129
2130 if (IpInstance->ConfigData.UseDefaultAddress && IP4_NO_MAPPING (IpInstance)) {
2131 Status = EFI_NO_MAPPING;
2132 goto ON_EXIT;
2133 }
2134
2135 Status = Ip4Cancel (IpInstance, Token);
2136
2137ON_EXIT:
2138 gBS->RestoreTPL (OldTpl);
2139 return Status;
2140}
2141
2170EFIAPI
2172 IN EFI_IP4_PROTOCOL *This
2173 )
2174{
2175 IP4_PROTOCOL *IpInstance;
2177
2178 if (This == NULL) {
2179 return EFI_INVALID_PARAMETER;
2180 }
2181
2182 IpInstance = IP4_INSTANCE_FROM_PROTOCOL (This);
2183
2184 if (IpInstance->State == IP4_STATE_UNCONFIGED) {
2185 return EFI_NOT_STARTED;
2186 }
2187
2188 Mnp = IpInstance->Service->Mnp;
2189
2190 //
2191 // Don't lock the Poll function to enable the deliver of
2192 // the packet polled up.
2193 //
2194 return Mnp->Poll (Mnp);
2195}
2196
2212EFIAPI
2214 IN NET_MAP *Map,
2215 IN NET_MAP_ITEM *Item,
2216 IN VOID *Context
2217 )
2218{
2219 IP4_TXTOKEN_WRAP *Wrap;
2220
2221 Wrap = (IP4_TXTOKEN_WRAP *)Item->Value;
2222 ASSERT (Wrap != NULL);
2223
2224 if ((Wrap->Life > 0) && (--Wrap->Life == 0)) {
2225 Ip4CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED);
2226 }
2227
2228 return EFI_SUCCESS;
2229}
2230
2240VOID
2241EFIAPI
2243 IN EFI_EVENT Event,
2244 IN VOID *Context
2245 )
2246{
2247 IP4_SERVICE *IpSb;
2248
2249 IpSb = (IP4_SERVICE *)Context;
2250 NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
2251
2252 Ip4PacketTimerTicking (IpSb);
2253 Ip4IgmpTicking (IpSb);
2254}
2255
2268VOID
2269EFIAPI
2271 IN EFI_EVENT Event,
2272 IN VOID *Context
2273 )
2274{
2275 IP4_SERVICE *IpSb;
2276 BOOLEAN OldMediaPresent;
2277 EFI_STATUS Status;
2278 EFI_SIMPLE_NETWORK_MODE SnpModeData;
2279
2280 IpSb = (IP4_SERVICE *)Context;
2281 NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
2282
2283 OldMediaPresent = IpSb->MediaPresent;
2284
2285 //
2286 // Get fresh mode data from MNP, since underlying media status may change.
2287 // Here, it needs to mention that the MediaPresent can also be checked even if
2288 // EFI_NOT_STARTED returned while this MNP child driver instance isn't configured.
2289 //
2290 Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &SnpModeData);
2291 if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
2292 return;
2293 }
2294
2295 IpSb->MediaPresent = SnpModeData.MediaPresent;
2296 //
2297 // Media transimit Unpresent to Present means new link movement is detected.
2298 //
2299 if (!OldMediaPresent && IpSb->MediaPresent && (IpSb->Ip4Config2Instance.Policy == Ip4Config2PolicyDhcp)) {
2300 //
2301 // Signal the IP4 to run the dhcp configuration again. IP4 driver will free
2302 // old IP address related resource, such as route table and Interface, then
2303 // initiate a DHCP round to acquire new IP, eventually
2304 // create route table for new IP address.
2305 //
2306 if (IpSb->ReconfigEvent != NULL) {
2307 Status = gBS->SignalEvent (IpSb->ReconfigEvent);
2308 DispatchDpc ();
2309 }
2310 }
2311}
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
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 CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI DispatchDpc(VOID)
Definition: DpcLib.c:86
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
INTN Ip4GetNetCast(IN IP4_ADDR IpAddr, IN IP4_INTERFACE *IpIf)
Definition: Ip4Common.c:26
IP4_HEAD * Ip4NtohHead(IN IP4_HEAD *Head)
Definition: Ip4Common.c:241
IP4_INTERFACE * Ip4FindStationAddress(IN IP4_SERVICE *IpSb, IN IP4_ADDR Ip, IN IP4_ADDR Netmask)
Definition: Ip4Common.c:183
BOOLEAN Ip4StationAddressValid(IN IP4_ADDR Ip, IN IP4_ADDR Netmask)
Definition: Ip4Common.c:267
#define IP4_US_TO_SEC(Us)
Definition: Ip4Common.h:69
#define IP4_HEAD_FRAGMENT_FIELD(Df, Mf, Offset)
Definition: Ip4Common.h:51
EFI_IP4_CONFIG2_POLICY
Definition: Ip4Config2.h:127
@ Ip4Config2PolicyDhcp
Definition: Ip4Config2.h:142
@ Ip4Config2DataTypePolicy
Definition: Ip4Config2.h:43
EFI_STATUS Ip4FreeInterface(IN IP4_INTERFACE *Interface, IN IP4_PROTOCOL *IpInstance OPTIONAL)
Definition: Ip4If.c:731
IP4_INTERFACE * Ip4CreateInterface(IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle)
Definition: Ip4If.c:477
EFI_STATUS Ip4SetAddress(IN OUT IP4_INTERFACE *Interface, IN IP4_ADDR IpAddr, IN IP4_ADDR SubnetMask)
Definition: Ip4If.c:547
EFI_STATUS Ip4JoinGroup(IN IP4_PROTOCOL *IpInstance, IN IP4_ADDR Address)
Definition: Ip4Igmp.c:253
VOID Ip4IgmpTicking(IN IP4_SERVICE *IpSb)
Definition: Ip4Igmp.c:501
EFI_STATUS Ip4LeaveGroup(IN IP4_PROTOCOL *IpInstance, IN IP4_ADDR Address)
Definition: Ip4Igmp.c:333
INTN Ip4RemoveGroupAddr(IN OUT IP4_ADDR *Groups, IN UINT32 Count, IN IP4_ADDR Addr)
Definition: Ip4Igmp.c:584
IP4_ADDR * Ip4CombineGroups(IN IP4_ADDR *Source, IN UINT32 Count, IN IP4_ADDR Addr)
Definition: Ip4Igmp.c:549
EFI_STATUS EFIAPI EfiIp4Poll(IN EFI_IP4_PROTOCOL *This)
Definition: Ip4Impl.c:2171
EFI_STATUS EFIAPI EfiIp4Receive(IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_COMPLETION_TOKEN *Token)
Definition: Ip4Impl.c:1842
EFI_STATUS Ip4TxTokenValid(IN EFI_IP4_COMPLETION_TOKEN *Token, IN IP4_INTERFACE *IpIf, IN BOOLEAN RawData)
Definition: Ip4Impl.c:1317
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 Ip4FreeTxToken(IN VOID *Context)
Definition: Ip4Impl.c:1455
EFI_STATUS EFIAPI Ip4CancelTxTokens(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: Ip4Impl.c:1918
VOID EFIAPI Ip4TimerTicking(IN EFI_EVENT Event, IN VOID *Context)
Definition: Ip4Impl.c:2242
VOID Ip4OnPacketSent(IP4_PROTOCOL *Ip4Instance, NET_BUF *Packet, EFI_STATUS IoStatus, UINT32 Flag, VOID *Context)
Definition: Ip4Impl.c:1504
EFI_STATUS EFIAPI EfiIp4Transmit(IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_COMPLETION_TOKEN *Token)
Definition: Ip4Impl.c:1564
EFI_STATUS Ip4Groups(IN IP4_PROTOCOL *IpInstance, IN BOOLEAN JoinFlag, IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL)
Definition: Ip4Impl.c:986
VOID EFIAPI Ip4TimerReconfigChecking(IN EFI_EVENT Event, IN VOID *Context)
Definition: Ip4Impl.c:2270
EFI_STATUS EFIAPI Ip4SentPacketTicking(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: Ip4Impl.c:2213
EFI_STATUS EFIAPI Ip4CancelRxTokens(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: Ip4Impl.c:1973
EFI_STATUS EFIAPI Ip4TokenExist(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: Ip4Impl.c:1285
EFI_STATUS EFIAPI EfiIp4Routes(IN EFI_IP4_PROTOCOL *This, IN BOOLEAN DeleteRoute, IN EFI_IPv4_ADDRESS *SubnetAddress, IN EFI_IPv4_ADDRESS *SubnetMask, IN EFI_IPv4_ADDRESS *GatewayAddress)
Definition: Ip4Impl.c:1194
EFI_STATUS EFIAPI EfiIp4Configure(IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL)
Definition: Ip4Impl.c:868
EFI_STATUS Ip4Cancel(IN IP4_PROTOCOL *IpInstance, IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL)
Definition: Ip4Impl.c:2016
EFI_STATUS EFIAPI EfiIp4Cancel(IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL)
Definition: Ip4Impl.c:2108
EFI_STATUS EFIAPI EfiIp4Groups(IN EFI_IP4_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL)
Definition: Ip4Impl.c:1099
EFI_STATUS EFIAPI EfiIp4GetModeData(IN CONST EFI_IP4_PROTOCOL *This, OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL)
Definition: Ip4Impl.c:363
EFI_STATUS Ip4ConfigProtocol(IN OUT IP4_PROTOCOL *IpInstance, IN EFI_IP4_CONFIG_DATA *Config)
Definition: Ip4Impl.c:578
EFI_STATUS Ip4CleanProtocol(IN IP4_PROTOCOL *IpInstance)
Definition: Ip4Impl.c:760
EFI_STATUS Ip4InstanceDeliverPacket(IN IP4_PROTOCOL *IpInstance)
Definition: Ip4Input.c:1256
VOID Ip4PacketTimerTicking(IN IP4_SERVICE *IpSb)
Definition: Ip4Input.c:1557
BOOLEAN Ip4OptionIsValid(IN UINT8 *Option, IN UINT32 OptionLen, IN BOOLEAN Rcvd)
Definition: Ip4Option.c:25
EFI_STATUS Ip4Output(IN IP4_SERVICE *IpSb, IN IP4_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN IP4_HEAD *Head, IN UINT8 *Option, IN UINT32 OptLen, IN IP4_ADDR GateWay, IN IP4_FRAME_CALLBACK Callback, IN VOID *Context)
Definition: Ip4Output.c:205
VOID Ip4CancelPacket(IN IP4_INTERFACE *IpIf, IN NET_BUF *Packet, IN EFI_STATUS IoStatus)
Definition: Ip4Output.c:467
EFI_STATUS Ip4BuildEfiRouteTable(IN IP4_PROTOCOL *IpInstance)
Definition: Ip4Route.c:593
EFI_STATUS Ip4DelRoute(IN OUT IP4_ROUTE_TABLE *RtTable, IN IP4_ADDR Dest, IN IP4_ADDR Netmask, IN IP4_ADDR Gateway)
Definition: Ip4Route.c:352
IP4_ROUTE_TABLE * Ip4CreateRouteTable(VOID)
Definition: Ip4Route.c:177
EFI_STATUS Ip4AddRoute(IN OUT IP4_ROUTE_TABLE *RtTable, IN IP4_ADDR Dest, IN IP4_ADDR Netmask, IN IP4_ADDR Gateway)
Definition: Ip4Route.c:291
VOID Ip4FreeRouteTable(IN IP4_ROUTE_TABLE *RtTable)
Definition: Ip4Route.c:211
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:195
VOID EFIAPI NetMapClean(IN OUT NET_MAP *Map)
Definition: DxeNetLib.c:1368
NET_MAP_ITEM *EFIAPI NetMapFindKey(IN NET_MAP *Map, IN VOID *Key)
Definition: DxeNetLib.c:1629
VOID EFIAPI NetMapInit(IN OUT NET_MAP *Map)
Definition: DxeNetLib.c:1343
NET_BUF *EFIAPI NetbufFromExt(IN NET_FRAGMENT *ExtFragment, IN UINT32 ExtNum, IN UINT32 HeadSpace, IN UINT32 HeadLen, IN NET_VECTOR_EXT_FREE ExtFree, IN VOID *Arg OPTIONAL)
Definition: NetBuffer.c:693
INTN EFIAPI NetGetIpClass(IN IP4_ADDR Addr)
Definition: DxeNetLib.c:643
BOOLEAN EFIAPI NetMapIsEmpty(IN NET_MAP *Map)
Definition: DxeNetLib.c:1413
VOID *EFIAPI NetMapRemoveItem(IN OUT NET_MAP *Map, IN OUT NET_MAP_ITEM *Item, OUT VOID **Value OPTIONAL)
Definition: DxeNetLib.c:1671
EFI_STATUS EFIAPI NetMapInsertTail(IN OUT NET_MAP *Map, IN VOID *Key, IN VOID *Value OPTIONAL)
Definition: DxeNetLib.c:1556
EFI_STATUS EFIAPI NetMapIterate(IN NET_MAP *Map, IN NET_MAP_CALLBACK CallBack, IN VOID *Arg OPTIONAL)
Definition: DxeNetLib.c:1800
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: UefiLib.c:405
EFI_EVENT Event
Definition: Ip4.h:244
EFI_IP4_RECEIVE_DATA * RxData
Definition: Ip4.h:254
EFI_STATUS Status
Definition: Ip4.h:249
UINT8 TypeOfService
Definition: Ip4.h:102
EFI_IPv4_ADDRESS SubnetMask
Definition: Ip4.h:98
UINT8 TimeToLive
Definition: Ip4.h:106
BOOLEAN AcceptPromiscuous
Definition: Ip4.h:86
BOOLEAN DoNotFragment
Definition: Ip4.h:110
UINT8 DefaultProtocol
Definition: Ip4.h:63
EFI_IPv4_ADDRESS StationAddress
Definition: Ip4.h:94
BOOLEAN RawData
Definition: Ip4.h:115
UINT32 TransmitTimeout
Definition: Ip4.h:127
BOOLEAN UseDefaultAddress
Definition: Ip4.h:90