|  | @@ -75,6 +75,10 @@ FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 );
 | 
		
	
		
			
			| 75 | 75 |  	__einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )
 | 
		
	
		
			
			| 76 | 76 |  #define EINFO_EINVAL_NO_TARGET_IQN \
 | 
		
	
		
			
			| 77 | 77 |  	__einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )
 | 
		
	
		
			
			|  | 78 | +#define EINVAL_NO_INITIATOR_IQN \
 | 
		
	
		
			
			|  | 79 | +	__einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )
 | 
		
	
		
			
			|  | 80 | +#define EINFO_EINVAL_NO_INITIATOR_IQN \
 | 
		
	
		
			
			|  | 81 | +	__einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )
 | 
		
	
		
			
			| 78 | 82 |  #define EIO_TARGET_UNAVAILABLE \
 | 
		
	
		
			
			| 79 | 83 |  	__einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )
 | 
		
	
		
			
			| 80 | 84 |  #define EINFO_EIO_TARGET_UNAVAILABLE \
 | 
		
	
	
		
			
			|  | @@ -128,24 +132,6 @@ FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 );
 | 
		
	
		
			
			| 128 | 132 |  #define EINFO_EPROTO_INVALID_CHAP_RESPONSE \
 | 
		
	
		
			
			| 129 | 133 |  	__einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )
 | 
		
	
		
			
			| 130 | 134 |  
 | 
		
	
		
			
			| 131 |  | -/** iSCSI initiator name (explicitly specified) */
 | 
		
	
		
			
			| 132 |  | -static char *iscsi_explicit_initiator_iqn;
 | 
		
	
		
			
			| 133 |  | -
 | 
		
	
		
			
			| 134 |  | -/** Default iSCSI initiator name (constructed from hostname) */
 | 
		
	
		
			
			| 135 |  | -static char *iscsi_default_initiator_iqn;
 | 
		
	
		
			
			| 136 |  | -
 | 
		
	
		
			
			| 137 |  | -/** iSCSI initiator username */
 | 
		
	
		
			
			| 138 |  | -static char *iscsi_initiator_username;
 | 
		
	
		
			
			| 139 |  | -
 | 
		
	
		
			
			| 140 |  | -/** iSCSI initiator password */
 | 
		
	
		
			
			| 141 |  | -static char *iscsi_initiator_password;
 | 
		
	
		
			
			| 142 |  | -
 | 
		
	
		
			
			| 143 |  | -/** iSCSI target username */
 | 
		
	
		
			
			| 144 |  | -static char *iscsi_target_username;
 | 
		
	
		
			
			| 145 |  | -
 | 
		
	
		
			
			| 146 |  | -/** iSCSI target password */
 | 
		
	
		
			
			| 147 |  | -static char *iscsi_target_password;
 | 
		
	
		
			
			| 148 |  | -
 | 
		
	
		
			
			| 149 | 135 |  static void iscsi_start_tx ( struct iscsi_session *iscsi );
 | 
		
	
		
			
			| 150 | 136 |  static void iscsi_start_login ( struct iscsi_session *iscsi );
 | 
		
	
		
			
			| 151 | 137 |  static void iscsi_start_data_out ( struct iscsi_session *iscsi,
 | 
		
	
	
		
			
			|  | @@ -200,6 +186,7 @@ static void iscsi_free ( struct refcnt *refcnt ) {
 | 
		
	
		
			
			| 200 | 186 |  	struct iscsi_session *iscsi =
 | 
		
	
		
			
			| 201 | 187 |  		container_of ( refcnt, struct iscsi_session, refcnt );
 | 
		
	
		
			
			| 202 | 188 |  
 | 
		
	
		
			
			|  | 189 | +	free ( iscsi->initiator_iqn );
 | 
		
	
		
			
			| 203 | 190 |  	free ( iscsi->target_address );
 | 
		
	
		
			
			| 204 | 191 |  	free ( iscsi->target_iqn );
 | 
		
	
		
			
			| 205 | 192 |  	free ( iscsi->initiator_username );
 | 
		
	
	
		
			
			|  | @@ -688,7 +675,7 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
 | 
		
	
		
			
			| 688 | 675 |  				    "TargetName=%s%c"
 | 
		
	
		
			
			| 689 | 676 |  				    "SessionType=Normal%c"
 | 
		
	
		
			
			| 690 | 677 |  				    "AuthMethod=%s%c",
 | 
		
	
		
			
			| 691 |  | -				    iscsi_initiator_iqn(), 0,
 | 
		
	
		
			
			|  | 678 | +				    iscsi->initiator_iqn, 0,
 | 
		
	
		
			
			| 692 | 679 |  				    iscsi->target_iqn, 0, 0,
 | 
		
	
		
			
			| 693 | 680 |  				    auth_method, 0 );
 | 
		
	
		
			
			| 694 | 681 |  	}
 | 
		
	
	
		
			
			|  | @@ -1832,6 +1819,30 @@ enum iscsi_root_path_component {
 | 
		
	
		
			
			| 1832 | 1819 |  	NUM_RP_COMPONENTS
 | 
		
	
		
			
			| 1833 | 1820 |  };
 | 
		
	
		
			
			| 1834 | 1821 |  
 | 
		
	
		
			
			|  | 1822 | +/** iSCSI initiator IQN setting */
 | 
		
	
		
			
			|  | 1823 | +struct setting initiator_iqn_setting __setting = {
 | 
		
	
		
			
			|  | 1824 | +	.name = "initiator-iqn",
 | 
		
	
		
			
			|  | 1825 | +	.description = "iSCSI initiator name",
 | 
		
	
		
			
			|  | 1826 | +	.tag = DHCP_ISCSI_INITIATOR_IQN,
 | 
		
	
		
			
			|  | 1827 | +	.type = &setting_type_string,
 | 
		
	
		
			
			|  | 1828 | +};
 | 
		
	
		
			
			|  | 1829 | +
 | 
		
	
		
			
			|  | 1830 | +/** iSCSI reverse username setting */
 | 
		
	
		
			
			|  | 1831 | +struct setting reverse_username_setting __setting = {
 | 
		
	
		
			
			|  | 1832 | +	.name = "reverse-username",
 | 
		
	
		
			
			|  | 1833 | +	.description = "Reverse user name",
 | 
		
	
		
			
			|  | 1834 | +	.tag = DHCP_EB_REVERSE_USERNAME,
 | 
		
	
		
			
			|  | 1835 | +	.type = &setting_type_string,
 | 
		
	
		
			
			|  | 1836 | +};
 | 
		
	
		
			
			|  | 1837 | +
 | 
		
	
		
			
			|  | 1838 | +/** iSCSI reverse password setting */
 | 
		
	
		
			
			|  | 1839 | +struct setting reverse_password_setting __setting = {
 | 
		
	
		
			
			|  | 1840 | +	.name = "reverse-password",
 | 
		
	
		
			
			|  | 1841 | +	.description = "Reverse password",
 | 
		
	
		
			
			|  | 1842 | +	.tag = DHCP_EB_REVERSE_PASSWORD,
 | 
		
	
		
			
			|  | 1843 | +	.type = &setting_type_string,
 | 
		
	
		
			
			|  | 1844 | +};
 | 
		
	
		
			
			|  | 1845 | +
 | 
		
	
		
			
			| 1835 | 1846 |  /**
 | 
		
	
		
			
			| 1836 | 1847 |   * Parse iSCSI root path
 | 
		
	
		
			
			| 1837 | 1848 |   *
 | 
		
	
	
		
			
			|  | @@ -1883,64 +1894,117 @@ static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
 | 
		
	
		
			
			| 1883 | 1894 |  }
 | 
		
	
		
			
			| 1884 | 1895 |  
 | 
		
	
		
			
			| 1885 | 1896 |  /**
 | 
		
	
		
			
			| 1886 |  | - * Set iSCSI authentication details
 | 
		
	
		
			
			|  | 1897 | + * Fetch iSCSI settings
 | 
		
	
		
			
			| 1887 | 1898 |   *
 | 
		
	
		
			
			| 1888 | 1899 |   * @v iscsi		iSCSI session
 | 
		
	
		
			
			| 1889 |  | - * @v initiator_username Initiator username, if any
 | 
		
	
		
			
			| 1890 |  | - * @v initiator_password Initiator password, if any
 | 
		
	
		
			
			| 1891 |  | - * @v target_username	Target username, if any
 | 
		
	
		
			
			| 1892 |  | - * @v target_password	Target password, if any
 | 
		
	
		
			
			| 1893 | 1900 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 1894 | 1901 |   */
 | 
		
	
		
			
			| 1895 |  | -static int iscsi_set_auth ( struct iscsi_session *iscsi,
 | 
		
	
		
			
			| 1896 |  | -			    const char *initiator_username,
 | 
		
	
		
			
			| 1897 |  | -			    const char *initiator_password,
 | 
		
	
		
			
			| 1898 |  | -			    const char *target_username,
 | 
		
	
		
			
			| 1899 |  | -			    const char *target_password ) {
 | 
		
	
		
			
			| 1900 |  | -
 | 
		
	
		
			
			| 1901 |  | -	/* Check for initiator or target credentials */
 | 
		
	
		
			
			| 1902 |  | -	if ( initiator_username || initiator_password ||
 | 
		
	
		
			
			| 1903 |  | -	     target_username || target_password ) {
 | 
		
	
		
			
			| 1904 |  | -
 | 
		
	
		
			
			| 1905 |  | -		/* We must have at least an initiator username+password */
 | 
		
	
		
			
			| 1906 |  | -		if ( ! ( initiator_username && initiator_password ) )
 | 
		
	
		
			
			| 1907 |  | -			goto invalid_auth;
 | 
		
	
		
			
			| 1908 |  | -
 | 
		
	
		
			
			| 1909 |  | -		/* Store initiator credentials */
 | 
		
	
		
			
			| 1910 |  | -		iscsi->initiator_username = strdup ( initiator_username );
 | 
		
	
		
			
			| 1911 |  | -		if ( ! iscsi->initiator_username )
 | 
		
	
		
			
			| 1912 |  | -			return -ENOMEM;
 | 
		
	
		
			
			| 1913 |  | -		iscsi->initiator_password = strdup ( initiator_password );
 | 
		
	
		
			
			| 1914 |  | -		if ( ! iscsi->initiator_password )
 | 
		
	
		
			
			| 1915 |  | -			return -ENOMEM;
 | 
		
	
		
			
			| 1916 |  | -
 | 
		
	
		
			
			| 1917 |  | -		/* Check for target credentials */
 | 
		
	
		
			
			| 1918 |  | -		if ( target_username || target_password ) {
 | 
		
	
		
			
			|  | 1902 | +static int iscsi_fetch_settings ( struct iscsi_session *iscsi ) {
 | 
		
	
		
			
			|  | 1903 | +	char *hostname;
 | 
		
	
		
			
			|  | 1904 | +	union uuid uuid;
 | 
		
	
		
			
			|  | 1905 | +	int len;
 | 
		
	
		
			
			| 1919 | 1906 |  
 | 
		
	
		
			
			| 1920 |  | -			/* We must have target username+password */
 | 
		
	
		
			
			| 1921 |  | -			if ( ! ( target_username && target_password ) )
 | 
		
	
		
			
			| 1922 |  | -				goto invalid_auth;
 | 
		
	
		
			
			|  | 1907 | +	/* Fetch relevant settings.  Don't worry about freeing on
 | 
		
	
		
			
			|  | 1908 | +	 * error, since iscsi_free() will take care of that anyway.
 | 
		
	
		
			
			|  | 1909 | +	 */
 | 
		
	
		
			
			|  | 1910 | +	if ( ( len = fetch_string_setting_copy ( NULL, &username_setting,
 | 
		
	
		
			
			|  | 1911 | +					  &iscsi->initiator_username ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1912 | +		DBGC ( iscsi, "iSCSI %p could not fetch username: %s\n",
 | 
		
	
		
			
			|  | 1913 | +		       iscsi, strerror ( len ) );
 | 
		
	
		
			
			|  | 1914 | +		return len;
 | 
		
	
		
			
			|  | 1915 | +	}
 | 
		
	
		
			
			|  | 1916 | +	if ( ( len = fetch_string_setting_copy ( NULL, &password_setting,
 | 
		
	
		
			
			|  | 1917 | +					  &iscsi->initiator_password ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1918 | +		DBGC ( iscsi, "iSCSI %p could not fetch password: %s\n",
 | 
		
	
		
			
			|  | 1919 | +		       iscsi, strerror ( len ) );
 | 
		
	
		
			
			|  | 1920 | +		return len;
 | 
		
	
		
			
			|  | 1921 | +	}
 | 
		
	
		
			
			|  | 1922 | +	if ( ( len = fetch_string_setting_copy( NULL, &reverse_username_setting,
 | 
		
	
		
			
			|  | 1923 | +					     &iscsi->target_username ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1924 | +		DBGC ( iscsi, "iSCSI %p could not fetch reverse username: %s\n",
 | 
		
	
		
			
			|  | 1925 | +		       iscsi, strerror ( len ) );
 | 
		
	
		
			
			|  | 1926 | +		return len;
 | 
		
	
		
			
			|  | 1927 | +	}
 | 
		
	
		
			
			|  | 1928 | +	if ( ( len = fetch_string_setting_copy( NULL, &reverse_password_setting,
 | 
		
	
		
			
			|  | 1929 | +					     &iscsi->target_password ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1930 | +		DBGC ( iscsi, "iSCSI %p could not fetch reverse password: %s\n",
 | 
		
	
		
			
			|  | 1931 | +		       iscsi, strerror ( len ) );
 | 
		
	
		
			
			|  | 1932 | +		return len;
 | 
		
	
		
			
			|  | 1933 | +	}
 | 
		
	
		
			
			| 1923 | 1934 |  
 | 
		
	
		
			
			| 1924 |  | -			/* Store target credentials */
 | 
		
	
		
			
			| 1925 |  | -			iscsi->target_username = strdup ( target_username );
 | 
		
	
		
			
			| 1926 |  | -			if ( ! iscsi->target_username )
 | 
		
	
		
			
			| 1927 |  | -				return -ENOMEM;
 | 
		
	
		
			
			| 1928 |  | -			iscsi->target_password = strdup ( target_password );
 | 
		
	
		
			
			| 1929 |  | -			if ( ! iscsi->target_password )
 | 
		
	
		
			
			| 1930 |  | -				return -ENOMEM;
 | 
		
	
		
			
			|  | 1935 | +	/* Find a suitable initiator name */
 | 
		
	
		
			
			|  | 1936 | +	if ( ( len = fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
 | 
		
	
		
			
			|  | 1937 | +					       &iscsi->initiator_iqn ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1938 | +		DBGC ( iscsi, "iSCSI %p could not fetch initiator IQN: %s\n",
 | 
		
	
		
			
			|  | 1939 | +		       iscsi, strerror ( len ) );
 | 
		
	
		
			
			|  | 1940 | +		return len;
 | 
		
	
		
			
			|  | 1941 | +	}
 | 
		
	
		
			
			|  | 1942 | +	if ( iscsi->initiator_iqn )
 | 
		
	
		
			
			|  | 1943 | +		return 0;
 | 
		
	
		
			
			|  | 1944 | +	if ( ( len = fetch_string_setting_copy ( NULL, &hostname_setting,
 | 
		
	
		
			
			|  | 1945 | +						&hostname ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1946 | +		DBGC ( iscsi, "iSCSI %p could not fetch hostname: %s\n",
 | 
		
	
		
			
			|  | 1947 | +		       iscsi, strerror ( len ) );
 | 
		
	
		
			
			|  | 1948 | +		return len;
 | 
		
	
		
			
			|  | 1949 | +	}
 | 
		
	
		
			
			|  | 1950 | +	if ( hostname ) {
 | 
		
	
		
			
			|  | 1951 | +		len = asprintf ( &iscsi->initiator_iqn,
 | 
		
	
		
			
			|  | 1952 | +				 ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
 | 
		
	
		
			
			|  | 1953 | +		free ( hostname );
 | 
		
	
		
			
			|  | 1954 | +		if ( len < 0 ) {
 | 
		
	
		
			
			|  | 1955 | +			DBGC ( iscsi, "iSCSI %p could not allocate initiator "
 | 
		
	
		
			
			|  | 1956 | +			       "IQN\n", iscsi );
 | 
		
	
		
			
			|  | 1957 | +			return -ENOMEM;
 | 
		
	
		
			
			| 1931 | 1958 |  		}
 | 
		
	
		
			
			|  | 1959 | +		assert ( iscsi->initiator_iqn );
 | 
		
	
		
			
			|  | 1960 | +		return 0;
 | 
		
	
		
			
			|  | 1961 | +	}
 | 
		
	
		
			
			|  | 1962 | +	if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1963 | +		DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
 | 
		
	
		
			
			|  | 1964 | +		       iscsi );
 | 
		
	
		
			
			|  | 1965 | +		return -EINVAL_NO_INITIATOR_IQN;
 | 
		
	
		
			
			|  | 1966 | +	}
 | 
		
	
		
			
			|  | 1967 | +	if ( ( len = asprintf ( &iscsi->initiator_iqn,
 | 
		
	
		
			
			|  | 1968 | +				ISCSI_DEFAULT_IQN_PREFIX ":%s",
 | 
		
	
		
			
			|  | 1969 | +				uuid_ntoa ( &uuid ) ) ) < 0 ) {
 | 
		
	
		
			
			|  | 1970 | +		DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
 | 
		
	
		
			
			|  | 1971 | +		       iscsi );
 | 
		
	
		
			
			|  | 1972 | +		return -ENOMEM;
 | 
		
	
		
			
			| 1932 | 1973 |  	}
 | 
		
	
		
			
			|  | 1974 | +	assert ( iscsi->initiator_iqn );
 | 
		
	
		
			
			| 1933 | 1975 |  
 | 
		
	
		
			
			| 1934 | 1976 |  	return 0;
 | 
		
	
		
			
			|  | 1977 | +}
 | 
		
	
		
			
			|  | 1978 | +
 | 
		
	
		
			
			| 1935 | 1979 |  
 | 
		
	
		
			
			| 1936 |  | - invalid_auth:
 | 
		
	
		
			
			| 1937 |  | -	DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
 | 
		
	
		
			
			| 1938 |  | -	       "%sname,%spw, target %sname,%spw\n", iscsi,
 | 
		
	
		
			
			| 1939 |  | -	       ( initiator_username ? "" : "no " ),
 | 
		
	
		
			
			| 1940 |  | -	       ( initiator_password ? "" : "no " ),
 | 
		
	
		
			
			| 1941 |  | -	       ( target_username ? "" : "no " ),
 | 
		
	
		
			
			| 1942 |  | -	       ( target_password ? "" : "no " ) );
 | 
		
	
		
			
			| 1943 |  | -	return -EINVAL_BAD_CREDENTIAL_MIX;
 | 
		
	
		
			
			|  | 1980 | +/**
 | 
		
	
		
			
			|  | 1981 | + * Check iSCSI authentication details
 | 
		
	
		
			
			|  | 1982 | + *
 | 
		
	
		
			
			|  | 1983 | + * @v iscsi		iSCSI session
 | 
		
	
		
			
			|  | 1984 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 1985 | + */
 | 
		
	
		
			
			|  | 1986 | +static int iscsi_check_auth ( struct iscsi_session *iscsi ) {
 | 
		
	
		
			
			|  | 1987 | +
 | 
		
	
		
			
			|  | 1988 | +	/* Check for invalid authentication combinations */
 | 
		
	
		
			
			|  | 1989 | +	if ( ( /* Initiator username without password (or vice-versa) */
 | 
		
	
		
			
			|  | 1990 | +		( !! iscsi->initiator_username ) ^
 | 
		
	
		
			
			|  | 1991 | +		( !! iscsi->initiator_password ) ) ||
 | 
		
	
		
			
			|  | 1992 | +	     ( /* Target username without password (or vice-versa) */
 | 
		
	
		
			
			|  | 1993 | +		( !! iscsi->target_username ) ^
 | 
		
	
		
			
			|  | 1994 | +		( !! iscsi->target_password ) ) ||
 | 
		
	
		
			
			|  | 1995 | +	     ( /* Target (reverse) without initiator (forward) */
 | 
		
	
		
			
			|  | 1996 | +		( iscsi->target_username &&
 | 
		
	
		
			
			|  | 1997 | +		  ( ! iscsi->initiator_username ) ) ) ) {
 | 
		
	
		
			
			|  | 1998 | +		DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
 | 
		
	
		
			
			|  | 1999 | +		       "%sname,%spw, target %sname,%spw\n", iscsi,
 | 
		
	
		
			
			|  | 2000 | +		       ( iscsi->initiator_username ? "" : "no " ),
 | 
		
	
		
			
			|  | 2001 | +		       ( iscsi->initiator_password ? "" : "no " ),
 | 
		
	
		
			
			|  | 2002 | +		       ( iscsi->target_username ? "" : "no " ),
 | 
		
	
		
			
			|  | 2003 | +		       ( iscsi->target_password ? "" : "no " ) );
 | 
		
	
		
			
			|  | 2004 | +		return -EINVAL_BAD_CREDENTIAL_MIX;
 | 
		
	
		
			
			|  | 2005 | +	}
 | 
		
	
		
			
			|  | 2006 | +
 | 
		
	
		
			
			|  | 2007 | +	return 0;
 | 
		
	
		
			
			| 1944 | 2008 |  }
 | 
		
	
		
			
			| 1945 | 2009 |  
 | 
		
	
		
			
			| 1946 | 2010 |  /**
 | 
		
	
	
		
			
			|  | @@ -1977,12 +2041,11 @@ static int iscsi_open ( struct interface *parent, struct uri *uri ) {
 | 
		
	
		
			
			| 1977 | 2041 |  	if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
 | 
		
	
		
			
			| 1978 | 2042 |  		goto err_parse_root_path;
 | 
		
	
		
			
			| 1979 | 2043 |  	/* Set fields not specified by root path */
 | 
		
	
		
			
			| 1980 |  | -	if ( ( rc = iscsi_set_auth ( iscsi,
 | 
		
	
		
			
			| 1981 |  | -				     iscsi_initiator_username,
 | 
		
	
		
			
			| 1982 |  | -				     iscsi_initiator_password,
 | 
		
	
		
			
			| 1983 |  | -				     iscsi_target_username,
 | 
		
	
		
			
			| 1984 |  | -				     iscsi_target_password ) ) != 0 )
 | 
		
	
		
			
			| 1985 |  | -		goto err_set_auth;
 | 
		
	
		
			
			|  | 2044 | +	if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
 | 
		
	
		
			
			|  | 2045 | +		goto err_fetch_settings;
 | 
		
	
		
			
			|  | 2046 | +	/* Validate authentication */
 | 
		
	
		
			
			|  | 2047 | +	if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
 | 
		
	
		
			
			|  | 2048 | +		goto err_check_auth;
 | 
		
	
		
			
			| 1986 | 2049 |  
 | 
		
	
		
			
			| 1987 | 2050 |  	/* Sanity checks */
 | 
		
	
		
			
			| 1988 | 2051 |  	if ( ! iscsi->target_address ) {
 | 
		
	
	
		
			
			|  | @@ -1997,6 +2060,9 @@ static int iscsi_open ( struct interface *parent, struct uri *uri ) {
 | 
		
	
		
			
			| 1997 | 2060 |  		rc = -EINVAL_NO_TARGET_IQN;
 | 
		
	
		
			
			| 1998 | 2061 |  		goto err_sanity_iqn;
 | 
		
	
		
			
			| 1999 | 2062 |  	}
 | 
		
	
		
			
			|  | 2063 | +	DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
 | 
		
	
		
			
			|  | 2064 | +	DBGC ( iscsi, "iSCSI %p target %s %s\n",
 | 
		
	
		
			
			|  | 2065 | +	       iscsi, iscsi->target_address, iscsi->target_iqn );
 | 
		
	
		
			
			| 2000 | 2066 |  
 | 
		
	
		
			
			| 2001 | 2067 |  	/* Open socket */
 | 
		
	
		
			
			| 2002 | 2068 |  	if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
 | 
		
	
	
		
			
			|  | @@ -2018,7 +2084,8 @@ static int iscsi_open ( struct interface *parent, struct uri *uri ) {
 | 
		
	
		
			
			| 2018 | 2084 |   err_open_connection:
 | 
		
	
		
			
			| 2019 | 2085 |   err_sanity_iqn:
 | 
		
	
		
			
			| 2020 | 2086 |   err_sanity_address:
 | 
		
	
		
			
			| 2021 |  | - err_set_auth:
 | 
		
	
		
			
			|  | 2087 | + err_check_auth:
 | 
		
	
		
			
			|  | 2088 | + err_fetch_settings:
 | 
		
	
		
			
			| 2022 | 2089 |   err_parse_root_path:
 | 
		
	
		
			
			| 2023 | 2090 |  	iscsi_close ( iscsi, rc );
 | 
		
	
		
			
			| 2024 | 2091 |  	ref_put ( &iscsi->refcnt );
 | 
		
	
	
		
			
			|  | @@ -2032,165 +2099,3 @@ struct uri_opener iscsi_uri_opener __uri_opener = {
 | 
		
	
		
			
			| 2032 | 2099 |  	.scheme = "iscsi",
 | 
		
	
		
			
			| 2033 | 2100 |  	.open = iscsi_open,
 | 
		
	
		
			
			| 2034 | 2101 |  };
 | 
		
	
		
			
			| 2035 |  | -
 | 
		
	
		
			
			| 2036 |  | -/****************************************************************************
 | 
		
	
		
			
			| 2037 |  | - *
 | 
		
	
		
			
			| 2038 |  | - * Settings
 | 
		
	
		
			
			| 2039 |  | - *
 | 
		
	
		
			
			| 2040 |  | - */
 | 
		
	
		
			
			| 2041 |  | -
 | 
		
	
		
			
			| 2042 |  | -/** iSCSI initiator IQN setting */
 | 
		
	
		
			
			| 2043 |  | -struct setting initiator_iqn_setting __setting = {
 | 
		
	
		
			
			| 2044 |  | -	.name = "initiator-iqn",
 | 
		
	
		
			
			| 2045 |  | -	.description = "iSCSI initiator name",
 | 
		
	
		
			
			| 2046 |  | -	.tag = DHCP_ISCSI_INITIATOR_IQN,
 | 
		
	
		
			
			| 2047 |  | -	.type = &setting_type_string,
 | 
		
	
		
			
			| 2048 |  | -};
 | 
		
	
		
			
			| 2049 |  | -
 | 
		
	
		
			
			| 2050 |  | -/** iSCSI reverse username setting */
 | 
		
	
		
			
			| 2051 |  | -struct setting reverse_username_setting __setting = {
 | 
		
	
		
			
			| 2052 |  | -	.name = "reverse-username",
 | 
		
	
		
			
			| 2053 |  | -	.description = "Reverse user name",
 | 
		
	
		
			
			| 2054 |  | -	.tag = DHCP_EB_REVERSE_USERNAME,
 | 
		
	
		
			
			| 2055 |  | -	.type = &setting_type_string,
 | 
		
	
		
			
			| 2056 |  | -};
 | 
		
	
		
			
			| 2057 |  | -
 | 
		
	
		
			
			| 2058 |  | -/** iSCSI reverse password setting */
 | 
		
	
		
			
			| 2059 |  | -struct setting reverse_password_setting __setting = {
 | 
		
	
		
			
			| 2060 |  | -	.name = "reverse-password",
 | 
		
	
		
			
			| 2061 |  | -	.description = "Reverse password",
 | 
		
	
		
			
			| 2062 |  | -	.tag = DHCP_EB_REVERSE_PASSWORD,
 | 
		
	
		
			
			| 2063 |  | -	.type = &setting_type_string,
 | 
		
	
		
			
			| 2064 |  | -};
 | 
		
	
		
			
			| 2065 |  | -
 | 
		
	
		
			
			| 2066 |  | -/** An iSCSI string setting */
 | 
		
	
		
			
			| 2067 |  | -struct iscsi_string_setting {
 | 
		
	
		
			
			| 2068 |  | -	/** Setting */
 | 
		
	
		
			
			| 2069 |  | -	struct setting *setting;
 | 
		
	
		
			
			| 2070 |  | -	/** String to update */
 | 
		
	
		
			
			| 2071 |  | -	char **string;
 | 
		
	
		
			
			| 2072 |  | -	/** String prefix */
 | 
		
	
		
			
			| 2073 |  | -	const char *prefix;
 | 
		
	
		
			
			| 2074 |  | -};
 | 
		
	
		
			
			| 2075 |  | -
 | 
		
	
		
			
			| 2076 |  | -/** iSCSI string settings */
 | 
		
	
		
			
			| 2077 |  | -static struct iscsi_string_setting iscsi_string_settings[] = {
 | 
		
	
		
			
			| 2078 |  | -	{
 | 
		
	
		
			
			| 2079 |  | -		.setting = &initiator_iqn_setting,
 | 
		
	
		
			
			| 2080 |  | -		.string = &iscsi_explicit_initiator_iqn,
 | 
		
	
		
			
			| 2081 |  | -		.prefix = "",
 | 
		
	
		
			
			| 2082 |  | -	},
 | 
		
	
		
			
			| 2083 |  | -	{
 | 
		
	
		
			
			| 2084 |  | -		.setting = &username_setting,
 | 
		
	
		
			
			| 2085 |  | -		.string = &iscsi_initiator_username,
 | 
		
	
		
			
			| 2086 |  | -		.prefix = "",
 | 
		
	
		
			
			| 2087 |  | -	},
 | 
		
	
		
			
			| 2088 |  | -	{
 | 
		
	
		
			
			| 2089 |  | -		.setting = &password_setting,
 | 
		
	
		
			
			| 2090 |  | -		.string = &iscsi_initiator_password,
 | 
		
	
		
			
			| 2091 |  | -		.prefix = "",
 | 
		
	
		
			
			| 2092 |  | -	},
 | 
		
	
		
			
			| 2093 |  | -	{
 | 
		
	
		
			
			| 2094 |  | -		.setting = &reverse_username_setting,
 | 
		
	
		
			
			| 2095 |  | -		.string = &iscsi_target_username,
 | 
		
	
		
			
			| 2096 |  | -		.prefix = "",
 | 
		
	
		
			
			| 2097 |  | -	},
 | 
		
	
		
			
			| 2098 |  | -	{
 | 
		
	
		
			
			| 2099 |  | -		.setting = &reverse_password_setting,
 | 
		
	
		
			
			| 2100 |  | -		.string = &iscsi_target_password,
 | 
		
	
		
			
			| 2101 |  | -		.prefix = "",
 | 
		
	
		
			
			| 2102 |  | -	},
 | 
		
	
		
			
			| 2103 |  | -	{
 | 
		
	
		
			
			| 2104 |  | -		.setting = &hostname_setting,
 | 
		
	
		
			
			| 2105 |  | -		.string = &iscsi_default_initiator_iqn,
 | 
		
	
		
			
			| 2106 |  | -		.prefix = "iqn.2000-01.org.etherboot:",
 | 
		
	
		
			
			| 2107 |  | -	},
 | 
		
	
		
			
			| 2108 |  | -};
 | 
		
	
		
			
			| 2109 |  | -
 | 
		
	
		
			
			| 2110 |  | -/**
 | 
		
	
		
			
			| 2111 |  | - * Apply iSCSI setting
 | 
		
	
		
			
			| 2112 |  | - *
 | 
		
	
		
			
			| 2113 |  | - * @v setting		iSCSI string setting
 | 
		
	
		
			
			| 2114 |  | - * @ret rc		Return status code
 | 
		
	
		
			
			| 2115 |  | - */
 | 
		
	
		
			
			| 2116 |  | -static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){
 | 
		
	
		
			
			| 2117 |  | -	size_t prefix_len;
 | 
		
	
		
			
			| 2118 |  | -	int setting_len;
 | 
		
	
		
			
			| 2119 |  | -	size_t len;
 | 
		
	
		
			
			| 2120 |  | -	int check_len;
 | 
		
	
		
			
			| 2121 |  | -	char *p;
 | 
		
	
		
			
			| 2122 |  | -
 | 
		
	
		
			
			| 2123 |  | -	/* Free old string */
 | 
		
	
		
			
			| 2124 |  | -	free ( *setting->string );
 | 
		
	
		
			
			| 2125 |  | -	*setting->string = NULL;
 | 
		
	
		
			
			| 2126 |  | -
 | 
		
	
		
			
			| 2127 |  | -	/* Allocate new string */
 | 
		
	
		
			
			| 2128 |  | -	prefix_len = strlen ( setting->prefix );
 | 
		
	
		
			
			| 2129 |  | -	setting_len = fetch_setting_len ( NULL, setting->setting );
 | 
		
	
		
			
			| 2130 |  | -	if ( setting_len < 0 ) {
 | 
		
	
		
			
			| 2131 |  | -		/* Missing settings are not errors; leave strings as NULL */
 | 
		
	
		
			
			| 2132 |  | -		return 0;
 | 
		
	
		
			
			| 2133 |  | -	}
 | 
		
	
		
			
			| 2134 |  | -	len = ( prefix_len + setting_len + 1 );
 | 
		
	
		
			
			| 2135 |  | -	p = *setting->string = malloc ( len );
 | 
		
	
		
			
			| 2136 |  | -	if ( ! p )
 | 
		
	
		
			
			| 2137 |  | -		return -ENOMEM;
 | 
		
	
		
			
			| 2138 |  | -
 | 
		
	
		
			
			| 2139 |  | -	/* Fill new string */
 | 
		
	
		
			
			| 2140 |  | -	strcpy ( p, setting->prefix );
 | 
		
	
		
			
			| 2141 |  | -	check_len = fetch_string_setting ( NULL, setting->setting,
 | 
		
	
		
			
			| 2142 |  | -					   ( p + prefix_len ),
 | 
		
	
		
			
			| 2143 |  | -					   ( len - prefix_len ) );
 | 
		
	
		
			
			| 2144 |  | -	assert ( check_len == setting_len );
 | 
		
	
		
			
			| 2145 |  | -
 | 
		
	
		
			
			| 2146 |  | -	return 0;
 | 
		
	
		
			
			| 2147 |  | -}
 | 
		
	
		
			
			| 2148 |  | -
 | 
		
	
		
			
			| 2149 |  | -/**
 | 
		
	
		
			
			| 2150 |  | - * Apply iSCSI settings
 | 
		
	
		
			
			| 2151 |  | - *
 | 
		
	
		
			
			| 2152 |  | - * @ret rc		Return status code
 | 
		
	
		
			
			| 2153 |  | - */
 | 
		
	
		
			
			| 2154 |  | -static int apply_iscsi_settings ( void ) {
 | 
		
	
		
			
			| 2155 |  | -	struct iscsi_string_setting *setting;
 | 
		
	
		
			
			| 2156 |  | -	unsigned int i;
 | 
		
	
		
			
			| 2157 |  | -	int rc;
 | 
		
	
		
			
			| 2158 |  | -
 | 
		
	
		
			
			| 2159 |  | -	for ( i = 0 ; i < ( sizeof ( iscsi_string_settings ) /
 | 
		
	
		
			
			| 2160 |  | -			    sizeof ( iscsi_string_settings[0] ) ) ; i++ ) {
 | 
		
	
		
			
			| 2161 |  | -		setting = &iscsi_string_settings[i];
 | 
		
	
		
			
			| 2162 |  | -		if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) {
 | 
		
	
		
			
			| 2163 |  | -			DBG ( "iSCSI could not apply setting %s\n",
 | 
		
	
		
			
			| 2164 |  | -			      setting->setting->name );
 | 
		
	
		
			
			| 2165 |  | -			return rc;
 | 
		
	
		
			
			| 2166 |  | -		}
 | 
		
	
		
			
			| 2167 |  | -	}
 | 
		
	
		
			
			| 2168 |  | -
 | 
		
	
		
			
			| 2169 |  | -	return 0;
 | 
		
	
		
			
			| 2170 |  | -}
 | 
		
	
		
			
			| 2171 |  | -
 | 
		
	
		
			
			| 2172 |  | -/** iSCSI settings applicator */
 | 
		
	
		
			
			| 2173 |  | -struct settings_applicator iscsi_settings_applicator __settings_applicator = {
 | 
		
	
		
			
			| 2174 |  | -	.apply = apply_iscsi_settings,
 | 
		
	
		
			
			| 2175 |  | -};
 | 
		
	
		
			
			| 2176 |  | -
 | 
		
	
		
			
			| 2177 |  | -/****************************************************************************
 | 
		
	
		
			
			| 2178 |  | - *
 | 
		
	
		
			
			| 2179 |  | - * Initiator name
 | 
		
	
		
			
			| 2180 |  | - *
 | 
		
	
		
			
			| 2181 |  | - */
 | 
		
	
		
			
			| 2182 |  | -
 | 
		
	
		
			
			| 2183 |  | -/**
 | 
		
	
		
			
			| 2184 |  | - * Get iSCSI initiator IQN
 | 
		
	
		
			
			| 2185 |  | - *
 | 
		
	
		
			
			| 2186 |  | - * @v iscsi		iSCSI session
 | 
		
	
		
			
			| 2187 |  | - * @ret rc		Return status code
 | 
		
	
		
			
			| 2188 |  | - */
 | 
		
	
		
			
			| 2189 |  | -const char * iscsi_initiator_iqn ( void ) {
 | 
		
	
		
			
			| 2190 |  | -
 | 
		
	
		
			
			| 2191 |  | -	if ( iscsi_explicit_initiator_iqn )
 | 
		
	
		
			
			| 2192 |  | -		return iscsi_explicit_initiator_iqn;
 | 
		
	
		
			
			| 2193 |  | -	if ( iscsi_default_initiator_iqn )
 | 
		
	
		
			
			| 2194 |  | -		return iscsi_default_initiator_iqn;
 | 
		
	
		
			
			| 2195 |  | -	return "iqn.2000-09.org.etherboot:UNKNOWN";
 | 
		
	
		
			
			| 2196 |  | -}
 |