NetworkPkg: Record user configured TargetIP/Port in iBFT

Current ISCSI driver records redirected iSCSI targetIP/Port in iBFT
once redirection occurs, which removes the possibility of the OS
to reconnect to the configured IP for load balancing. The behavior
is not explicitly described in IBFT spec, though the MSFT expert
confirm we should record original user setting rather than
publish the redirected IP.

Thanks Sriram for reviewing and validating this patch in his test-bed.

Cc: Subramanian Sriram <sriram-s@hpe.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Subramanian Sriram <sriram-s@hpe.com>
This commit is contained in:
Ye Ting 2016-09-29 13:52:05 +08:00
parent 08354c3448
commit a2d59ef291
4 changed files with 55 additions and 17 deletions

View File

@ -358,6 +358,7 @@ IScsiStart (
VOID *Interface;
EFI_GUID *ProtocolGuid;
UINT8 NetworkBootPolicy;
ISCSI_SESSION_CONFIG_NVDATA *NvData;
//
// Test to see if iSCSI driver supports the given controller.
@ -701,6 +702,24 @@ IScsiStart (
Status = IScsiSessionReLogin (Session);
}
//
// Restore the origial user setting which specifies the proxy/virtual iSCSI target to NV region.
//
NvData = &AttemptConfigData->SessionConfigData;
if (NvData->RedirectFlag) {
NvData->TargetPort = NvData->OriginalTargetPort;
CopyMem (&NvData->TargetIp, &NvData->OriginalTargetIp, sizeof (EFI_IP_ADDRESS));
NvData->RedirectFlag = FALSE;
gRT->SetVariable (
mPrivate->PortString,
&gEfiIScsiInitiatorNameProtocolGuid,
ISCSI_CONFIG_VAR_ATTR,
sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
AttemptConfigData
);
}
if (EFI_ERROR (Status)) {
//
// In Single path mode, only the successful attempt will be recorded in iBFT;

View File

@ -1188,11 +1188,11 @@ IScsiGetConfigData (
);
GetVariable2 (
mPrivate->PortString,
&gEfiIScsiInitiatorNameProtocolGuid,
(VOID**)&AttemptConfigData,
NULL
);
mPrivate->PortString,
&gEfiIScsiInitiatorNameProtocolGuid,
(VOID**)&AttemptConfigData,
NULL
);
if (AttemptConfigData == NULL) {
continue;

View File

@ -50,9 +50,14 @@ typedef struct _ISCSI_SESSION_CONFIG_NVDATA {
UINT8 PrefixLength;
UINT8 BootLun[8];
UINT16 ConnectTimeout; ///< timout value in milliseconds
UINT16 ConnectTimeout; ///< timout value in milliseconds.
UINT8 ConnectRetryCount;
UINT8 IsId[6];
BOOLEAN RedirectFlag;
UINT16 OriginalTargetPort; // The port of proxy/virtual target.
EFI_IP_ADDRESS OriginalTargetIp; // The address of proxy/virtual target.
} ISCSI_SESSION_CONFIG_NVDATA;
#pragma pack()

View File

@ -1069,12 +1069,13 @@ IScsiUpdateTargetAddress (
IN UINT32 Len
)
{
LIST_ENTRY *KeyValueList;
CHAR8 *TargetAddress;
CHAR8 *IpStr;
EFI_STATUS Status;
UINTN Number;
UINT8 IpMode;
LIST_ENTRY *KeyValueList;
CHAR8 *TargetAddress;
CHAR8 *IpStr;
EFI_STATUS Status;
UINTN Number;
UINT8 IpMode;
ISCSI_SESSION_CONFIG_NVDATA *NvData;
KeyValueList = IScsiBuildKeyValueList (Data, Len);
if (KeyValueList == NULL) {
@ -1082,7 +1083,8 @@ IScsiUpdateTargetAddress (
}
Status = EFI_NOT_FOUND;
NvData = &Session->ConfigData->SessionConfigData;
while (TRUE) {
TargetAddress = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ADDRESS);
if (TargetAddress == NULL) {
@ -1098,6 +1100,11 @@ IScsiUpdateTargetAddress (
continue;
}
//
// Save the origial user setting which specifies the proxy/virtual iSCSI target.
//
NvData->OriginalTargetPort = NvData->TargetPort;
IpStr = TargetAddress;
while ((*TargetAddress != 0) && (*TargetAddress != ':') && (*TargetAddress != ',')) {
@ -1122,19 +1129,25 @@ IScsiUpdateTargetAddress (
if (Number > 0xFFFF) {
continue;
} else {
Session->ConfigData->SessionConfigData.TargetPort = (UINT16) Number;
NvData->TargetPort = (UINT16) Number;
}
} else {
//
// The string only contains the IPv4 address. Use the well-known port.
//
Session->ConfigData->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;
NvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
}
//
// Save the origial user setting which specifies the proxy/virtual iSCSI target.
//
CopyMem (&NvData->OriginalTargetIp, &NvData->TargetIp, sizeof (EFI_IP_ADDRESS));
//
// Update the target IP address.
//
if (Session->ConfigData->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {
IpMode = Session->ConfigData->SessionConfigData.IpMode;
if (NvData->IpMode < IP_MODE_AUTOCONFIG) {
IpMode = NvData->IpMode;
} else {
IpMode = Session->ConfigData->AutoConfigureMode;
}
@ -1148,6 +1161,7 @@ IScsiUpdateTargetAddress (
if (EFI_ERROR (Status)) {
continue;
} else {
NvData->RedirectFlag = TRUE;
break;
}
}