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:
sfu5
2012-12-13 06:47:06 +00:00
parent 906e1cb7f7
commit 216f79703b
91 changed files with 3991 additions and 694 deletions

View File

@@ -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;