1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
2. Fix the driver binding Stop() hang issue in the network stack. 3. Add Ip4 raw data support. 4. Add iSCSI Dhcp option 60 support. Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Ouyang Qian <qian.ouyang@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13995 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -868,6 +868,7 @@ Ip4ConfigProtocol (
|
||||
EFI_STATUS Status;
|
||||
IP4_ADDR Ip;
|
||||
IP4_ADDR Netmask;
|
||||
EFI_ARP_PROTOCOL *Arp;
|
||||
|
||||
IpSb = IpInstance->Service;
|
||||
|
||||
@@ -972,6 +973,20 @@ Ip4ConfigProtocol (
|
||||
}
|
||||
|
||||
IpInstance->Interface = IpIf;
|
||||
if (IpIf->Arp != NULL) {
|
||||
Arp = NULL;
|
||||
Status = gBS->OpenProtocol (
|
||||
IpIf->ArpHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID **) &Arp,
|
||||
gIp4DriverBinding.DriverBindingHandle,
|
||||
IpInstance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
}
|
||||
InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
|
||||
|
||||
CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
|
||||
@@ -1028,6 +1043,14 @@ Ip4CleanProtocol (
|
||||
|
||||
if (IpInstance->Interface != NULL) {
|
||||
RemoveEntryList (&IpInstance->AddrLink);
|
||||
if (IpInstance->Interface->Arp != NULL) {
|
||||
gBS->CloseProtocol (
|
||||
IpInstance->Interface->ArpHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
gIp4DriverBinding.DriverBindingHandle,
|
||||
IpInstance->Handle
|
||||
);
|
||||
}
|
||||
Ip4FreeInterface (IpInstance->Interface, IpInstance);
|
||||
IpInstance->Interface = NULL;
|
||||
}
|
||||
@@ -1193,14 +1216,6 @@ EfiIp4Configure (
|
||||
// Validate the configuration first.
|
||||
//
|
||||
if (IpConfigData != NULL) {
|
||||
//
|
||||
// This implementation doesn't support RawData
|
||||
//
|
||||
if (IpConfigData->RawData) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
|
||||
CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR));
|
||||
CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR));
|
||||
@@ -1620,22 +1635,23 @@ Ip4TokenExist (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Validate the user's token against current station address.
|
||||
|
||||
@param[in] Token User's token to validate
|
||||
@param[in] IpIf The IP4 child's interface.
|
||||
@param[in] Token User's token to validate.
|
||||
@param[in] IpIf The IP4 child's interface.
|
||||
@param[in] RawData Set to TRUE to send unformatted packets.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Some parameters are invalid
|
||||
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
|
||||
@retval EFI_BAD_BUFFER_SIZE The user's option/data is too long.
|
||||
@retval EFI_SUCCESS The token is OK
|
||||
@retval EFI_SUCCESS The token is valid.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Ip4TxTokenValid (
|
||||
IN EFI_IP4_COMPLETION_TOKEN *Token,
|
||||
IN IP4_INTERFACE *IpIf
|
||||
IN IP4_INTERFACE *IpIf,
|
||||
IN BOOLEAN RawData
|
||||
)
|
||||
{
|
||||
EFI_IP4_TRANSMIT_DATA *TxData;
|
||||
@@ -1653,20 +1669,7 @@ Ip4TxTokenValid (
|
||||
TxData = Token->Packet.TxData;
|
||||
|
||||
//
|
||||
// Check the IP options: no more than 40 bytes and format is OK
|
||||
//
|
||||
if (TxData->OptionsLength != 0) {
|
||||
if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check the fragment table: no empty fragment, and length isn't bogus
|
||||
// Check the fragment table: no empty fragment, and length isn't bogus.
|
||||
//
|
||||
if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@@ -1674,6 +1677,10 @@ Ip4TxTokenValid (
|
||||
|
||||
Offset = TxData->TotalDataLength;
|
||||
|
||||
if (Offset > IP4_MAX_PACKET_SIZE) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < TxData->FragmentCount; Index++) {
|
||||
if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||
|
||||
(TxData->FragmentTable[Index].FragmentLength == 0)) {
|
||||
@@ -1688,6 +1695,27 @@ Ip4TxTokenValid (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData
|
||||
// is TRUE.
|
||||
//
|
||||
if (RawData) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the IP options: no more than 40 bytes and format is OK
|
||||
//
|
||||
if (TxData->OptionsLength != 0) {
|
||||
if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check the source and gateway: they must be a valid unicast.
|
||||
// Gateway must also be on the connected network.
|
||||
@@ -1888,6 +1916,10 @@ EfiIp4Transmit (
|
||||
EFI_TPL OldTpl;
|
||||
BOOLEAN DontFragment;
|
||||
UINT32 HeadLen;
|
||||
UINT8 RawHdrLen;
|
||||
UINT32 OptionsLength;
|
||||
UINT8 *OptionsBuffer;
|
||||
VOID *FirstFragment;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@@ -1913,7 +1945,7 @@ EfiIp4Transmit (
|
||||
//
|
||||
// make sure that token is properly formated
|
||||
//
|
||||
Status = Ip4TxTokenValid (Token, IpIf);
|
||||
Status = Ip4TxTokenValid (Token, IpIf, Config->RawData);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
@@ -1933,32 +1965,82 @@ EfiIp4Transmit (
|
||||
//
|
||||
TxData = Token->Packet.TxData;
|
||||
|
||||
CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
|
||||
Head.Dst = NTOHL (Head.Dst);
|
||||
FirstFragment = NULL;
|
||||
|
||||
if (TxData->OverrideData != NULL) {
|
||||
Override = TxData->OverrideData;
|
||||
Head.Protocol = Override->Protocol;
|
||||
Head.Tos = Override->TypeOfService;
|
||||
Head.Ttl = Override->TimeToLive;
|
||||
DontFragment = Override->DoNotFragment;
|
||||
if (Config->RawData) {
|
||||
//
|
||||
// When RawData is TRUE, first buffer in FragmentTable points to a raw
|
||||
// IPv4 fragment including IPv4 header and options.
|
||||
//
|
||||
FirstFragment = TxData->FragmentTable[0].FragmentBuffer;
|
||||
CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8));
|
||||
|
||||
CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
|
||||
CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
|
||||
RawHdrLen = (UINT8) (RawHdrLen & 0x0f);
|
||||
if (RawHdrLen < 5) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Head.Src = NTOHL (Head.Src);
|
||||
GateWay = NTOHL (GateWay);
|
||||
RawHdrLen = (UINT8) (RawHdrLen << 2);
|
||||
|
||||
CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);
|
||||
|
||||
Ip4NtohHead (&Head);
|
||||
HeadLen = 0;
|
||||
DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);
|
||||
|
||||
if (!DontFragment) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
GateWay = IP4_ALLZERO_ADDRESS;
|
||||
|
||||
//
|
||||
// Get IPv4 options from first fragment.
|
||||
//
|
||||
if (RawHdrLen == IP4_MIN_HEADLEN) {
|
||||
OptionsLength = 0;
|
||||
OptionsBuffer = NULL;
|
||||
} else {
|
||||
OptionsLength = RawHdrLen - IP4_MIN_HEADLEN;
|
||||
OptionsBuffer = (UINT8 *) FirstFragment + IP4_MIN_HEADLEN;
|
||||
}
|
||||
|
||||
//
|
||||
// Trim off IPv4 header and options from first fragment.
|
||||
//
|
||||
TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment + RawHdrLen;
|
||||
TxData->FragmentTable[0].FragmentLength = TxData->FragmentTable[0].FragmentLength - RawHdrLen;
|
||||
} else {
|
||||
Head.Src = IpIf->Ip;
|
||||
GateWay = IP4_ALLZERO_ADDRESS;
|
||||
Head.Protocol = Config->DefaultProtocol;
|
||||
Head.Tos = Config->TypeOfService;
|
||||
Head.Ttl = Config->TimeToLive;
|
||||
DontFragment = Config->DoNotFragment;
|
||||
}
|
||||
CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
|
||||
Head.Dst = NTOHL (Head.Dst);
|
||||
|
||||
Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
|
||||
HeadLen = (TxData->OptionsLength + 3) & (~0x03);
|
||||
if (TxData->OverrideData != NULL) {
|
||||
Override = TxData->OverrideData;
|
||||
Head.Protocol = Override->Protocol;
|
||||
Head.Tos = Override->TypeOfService;
|
||||
Head.Ttl = Override->TimeToLive;
|
||||
DontFragment = Override->DoNotFragment;
|
||||
|
||||
CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
|
||||
CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
|
||||
|
||||
Head.Src = NTOHL (Head.Src);
|
||||
GateWay = NTOHL (GateWay);
|
||||
} else {
|
||||
Head.Src = IpIf->Ip;
|
||||
GateWay = IP4_ALLZERO_ADDRESS;
|
||||
Head.Protocol = Config->DefaultProtocol;
|
||||
Head.Tos = Config->TypeOfService;
|
||||
Head.Ttl = Config->TimeToLive;
|
||||
DontFragment = Config->DoNotFragment;
|
||||
}
|
||||
|
||||
Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
|
||||
HeadLen = (TxData->OptionsLength + 3) & (~0x03);
|
||||
|
||||
OptionsLength = TxData->OptionsLength;
|
||||
OptionsBuffer = (UINT8 *) (TxData->OptionsBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// If don't fragment and fragment needed, return error
|
||||
@@ -2004,6 +2086,13 @@ EfiIp4Transmit (
|
||||
// free the IP4_TXTOKEN_WRAP. Now, the token wrap hasn't been
|
||||
// enqueued.
|
||||
//
|
||||
if (Config->RawData) {
|
||||
//
|
||||
// Restore pointer of first fragment in RawData mode.
|
||||
//
|
||||
TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
|
||||
}
|
||||
|
||||
NetbufFree (Wrap->Packet);
|
||||
goto ON_EXIT;
|
||||
}
|
||||
@@ -2019,8 +2108,8 @@ EfiIp4Transmit (
|
||||
IpInstance,
|
||||
Wrap->Packet,
|
||||
&Head,
|
||||
TxData->OptionsBuffer,
|
||||
TxData->OptionsLength,
|
||||
OptionsBuffer,
|
||||
OptionsLength,
|
||||
GateWay,
|
||||
Ip4OnPacketSent,
|
||||
Wrap
|
||||
@@ -2028,9 +2117,24 @@ EfiIp4Transmit (
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Wrap->Sent = FALSE;
|
||||
|
||||
if (Config->RawData) {
|
||||
//
|
||||
// Restore pointer of first fragment in RawData mode.
|
||||
//
|
||||
TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
|
||||
}
|
||||
|
||||
NetbufFree (Wrap->Packet);
|
||||
}
|
||||
|
||||
if (Config->RawData) {
|
||||
//
|
||||
// Restore pointer of first fragment in RawData mode.
|
||||
//
|
||||
TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
|
Reference in New Issue
Block a user