/** @file\r
The implementation of iSCSI protocol based on RFC3720.\r
\r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
Conn->PartialRspRcvd = FALSE;\r
Conn->ParamNegotiated = FALSE;\r
Conn->Cid = Session->NextCid++;\r
- Conn->Ipv6Flag = mPrivate->Ipv6Flag;\r
+ Conn->Ipv6Flag = NvData->IpMode == IP_MODE_IP6 || Session->ConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6;\r
\r
Status = gBS->CreateEvent (\r
EVT_TIMER,\r
CopyMem (&Tcp4IoConfig->Gateway, &NvData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
CopyMem (&Tcp4IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
\r
- Tcp4IoConfig->RemotePort = NvData->TargetPort;\r
- Tcp4IoConfig->ActiveFlag = TRUE;\r
-\r
+ Tcp4IoConfig->RemotePort = NvData->TargetPort;\r
+ Tcp4IoConfig->ActiveFlag = TRUE;\r
+ Tcp4IoConfig->StationPort = 0;\r
} else {\r
Tcp6IoConfig = &TcpIoConfig.Tcp6IoConfigData;\r
\r
CopyMem (&Tcp6IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));\r
- Tcp6IoConfig->RemotePort = NvData->TargetPort;\r
- Tcp6IoConfig->ActiveFlag = TRUE;\r
+ Tcp6IoConfig->RemotePort = NvData->TargetPort;\r
+ Tcp6IoConfig->ActiveFlag = TRUE;\r
+ Tcp6IoConfig->StationPort = 0;\r
}\r
\r
//\r
FreePool (Conn);\r
}\r
\r
+/**\r
+ Retrieve the IPv6 Address/Prefix/Gateway from the established TCP connection, these informations\r
+ will be filled in the iSCSI Boot Firmware Table.\r
+\r
+ @param[in] Conn The connection used in the iSCSI login phase.\r
+\r
+ @retval EFI_SUCCESS Get the NIC information successfully.\r
+ @retval Others Other errors as indicated.\r
+ \r
+**/\r
+EFI_STATUS\r
+IScsiGetIp6NicInfo (\r
+ IN ISCSI_CONNECTION *Conn\r
+ )\r
+{\r
+ ISCSI_SESSION_CONFIG_NVDATA *NvData;\r
+ EFI_TCP6_PROTOCOL *Tcp6;\r
+ EFI_IP6_MODE_DATA Ip6ModeData;\r
+ EFI_STATUS Status;\r
+ EFI_IPv6_ADDRESS *TargetIp;\r
+ UINTN Index;\r
+ UINT8 SubnetPrefixLength;\r
+ UINTN RouteEntry;\r
+\r
+ NvData = &Conn->Session->ConfigData->SessionConfigData;\r
+ TargetIp = &NvData->TargetIp.v6;\r
+ Tcp6 = Conn->TcpIo.Tcp.Tcp6;\r
+\r
+ ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));\r
+ Status = Tcp6->GetModeData (\r
+ Tcp6,\r
+ NULL,\r
+ NULL,\r
+ &Ip6ModeData,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (!Ip6ModeData.IsConfigured) {\r
+ Status = EFI_ABORTED;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ IP6_COPY_ADDRESS (&NvData->LocalIp, &Ip6ModeData.ConfigData.StationAddress);\r
+\r
+ NvData->PrefixLength = 0;\r
+ for (Index = 0; Index < Ip6ModeData.AddressCount; Index++) {\r
+ if (EFI_IP6_EQUAL (&NvData->LocalIp.v6, &Ip6ModeData.AddressList[Index].Address)) {\r
+ NvData->PrefixLength = Ip6ModeData.AddressList[Index].PrefixLength;\r
+ break;\r
+ }\r
+ }\r
+\r
+ SubnetPrefixLength = 0;\r
+ RouteEntry = Ip6ModeData.RouteCount;\r
+ for (Index = 0; Index < Ip6ModeData.RouteCount; Index++) {\r
+ if (NetIp6IsNetEqual (TargetIp, &Ip6ModeData.RouteTable[Index].Destination, Ip6ModeData.RouteTable[Index].PrefixLength)) {\r
+ if (SubnetPrefixLength < Ip6ModeData.RouteTable[Index].PrefixLength) {\r
+ SubnetPrefixLength = Ip6ModeData.RouteTable[Index].PrefixLength;\r
+ RouteEntry = Index;\r
+ }\r
+ }\r
+ }\r
+ if (RouteEntry != Ip6ModeData.RouteCount) {\r
+ IP6_COPY_ADDRESS (&NvData->Gateway, &Ip6ModeData.RouteTable[RouteEntry].Gateway);\r
+ }\r
+\r
+ON_EXIT:\r
+ if (Ip6ModeData.AddressList != NULL) {\r
+ FreePool (Ip6ModeData.AddressList);\r
+ }\r
+ if (Ip6ModeData.GroupTable!= NULL) {\r
+ FreePool (Ip6ModeData.GroupTable);\r
+ }\r
+ if (Ip6ModeData.RouteTable!= NULL) {\r
+ FreePool (Ip6ModeData.RouteTable);\r
+ }\r
+ if (Ip6ModeData.NeighborCache!= NULL) {\r
+ FreePool (Ip6ModeData.NeighborCache);\r
+ }\r
+ if (Ip6ModeData.PrefixTable!= NULL) {\r
+ FreePool (Ip6ModeData.PrefixTable);\r
+ }\r
+ if (Ip6ModeData.IcmpTypeList!= NULL) {\r
+ FreePool (Ip6ModeData.IcmpTypeList);\r
+ }\r
+\r
+ return Status;\r
+}\r
\r
/**\r
Login the iSCSI session.\r
if (!EFI_ERROR (Status)) {\r
Session->State = SESSION_STATE_LOGGED_IN;\r
\r
- if (!mPrivate->Ipv6Flag) {\r
+ if (!Conn->Ipv6Flag) {\r
ProtocolGuid = &gEfiTcp4ProtocolGuid; \r
} else {\r
ProtocolGuid = &gEfiTcp6ProtocolGuid;\r
);\r
\r
ASSERT_EFI_ERROR (Status);\r
+\r
+ if (Conn->Ipv6Flag) {\r
+ Status = IScsiGetIp6NicInfo (Conn);\r
+ }\r
}\r
\r
return Status;\r
Timeout = 0;\r
\r
if (Session->State != SESSION_STATE_LOGGED_IN) {\r
- return EFI_DEVICE_ERROR;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto ON_EXIT;\r
}\r
\r
Conn = NET_LIST_USER_STRUCT_S (\r
{\r
EFI_STATUS Status;\r
\r
- ASSERT (Session->State == SESSION_STATE_LOGGED_IN);\r
+ ASSERT (Session->State != SESSION_STATE_FREE);\r
\r
//\r
// Abort the session and re-init it.\r