aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-05-30 13:57:24 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-02 15:37:19 -0400
commit2223696192c687f2853e42b7c1e0d3ef002081fd (patch)
tree9eef082af7f3286781134226bfc98ec401d41e79
parent4e7aba73f9f6e9fe6d3fa10d3fd63cd4882ba3d0 (diff)
[SCSI] iscsi class, qla4xxx, iscsi_tcp: export local address
This patch exports the local address for the session. For qla4xxx this is the ip of the hba's port. For software this is the src addr of the socket. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Cc: David C Somayajulu <david.somayajulu@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/iscsi_tcp.c127
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c8
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c4
-rw-r--r--include/scsi/iscsi_if.h2
-rw-r--r--include/scsi/libiscsi.h8
5 files changed, 118 insertions, 31 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7ce177e30a53..da66fb524b5b 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1870,18 +1870,22 @@ tcp_conn_alloc_fail:
1870static void 1870static void
1871iscsi_tcp_release_conn(struct iscsi_conn *conn) 1871iscsi_tcp_release_conn(struct iscsi_conn *conn)
1872{ 1872{
1873 struct iscsi_session *session = conn->session;
1873 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1874 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1875 struct socket *sock = tcp_conn->sock;
1874 1876
1875 if (!tcp_conn->sock) 1877 if (!sock)
1876 return; 1878 return;
1877 1879
1878 sock_hold(tcp_conn->sock->sk); 1880 sock_hold(sock->sk);
1879 iscsi_conn_restore_callbacks(tcp_conn); 1881 iscsi_conn_restore_callbacks(tcp_conn);
1880 sock_put(tcp_conn->sock->sk); 1882 sock_put(sock->sk);
1881 1883
1882 sockfd_put(tcp_conn->sock); 1884 spin_lock_bh(&session->lock);
1883 tcp_conn->sock = NULL; 1885 tcp_conn->sock = NULL;
1884 conn->recv_lock = NULL; 1886 conn->recv_lock = NULL;
1887 spin_unlock_bh(&session->lock);
1888 sockfd_put(sock);
1885} 1889}
1886 1890
1887static void 1891static void
@@ -1912,6 +1916,46 @@ iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
1912 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 1916 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1913} 1917}
1914 1918
1919static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock,
1920 char *buf, int *port,
1921 int (*getname)(struct socket *, struct sockaddr *,
1922 int *addrlen))
1923{
1924 struct sockaddr_storage *addr;
1925 struct sockaddr_in6 *sin6;
1926 struct sockaddr_in *sin;
1927 int rc = 0, len;
1928
1929 addr = kmalloc(GFP_KERNEL, sizeof(*addr));
1930 if (!addr)
1931 return -ENOMEM;
1932
1933 if (getname(sock, (struct sockaddr *) addr, &len)) {
1934 rc = -ENODEV;
1935 goto free_addr;
1936 }
1937
1938 switch (addr->ss_family) {
1939 case AF_INET:
1940 sin = (struct sockaddr_in *)addr;
1941 spin_lock_bh(&conn->session->lock);
1942 sprintf(buf, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
1943 *port = be16_to_cpu(sin->sin_port);
1944 spin_unlock_bh(&conn->session->lock);
1945 break;
1946 case AF_INET6:
1947 sin6 = (struct sockaddr_in6 *)addr;
1948 spin_lock_bh(&conn->session->lock);
1949 sprintf(buf, NIP6_FMT, NIP6(sin6->sin6_addr));
1950 *port = be16_to_cpu(sin6->sin6_port);
1951 spin_unlock_bh(&conn->session->lock);
1952 break;
1953 }
1954free_addr:
1955 kfree(addr);
1956 return rc;
1957}
1958
1915static int 1959static int
1916iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, 1960iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1917 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, 1961 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
@@ -1929,10 +1973,24 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1929 printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err); 1973 printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
1930 return -EEXIST; 1974 return -EEXIST;
1931 } 1975 }
1976 /*
1977 * copy these values now because if we drop the session
1978 * userspace may still want to query the values since we will
1979 * be using them for the reconnect
1980 */
1981 err = iscsi_tcp_get_addr(conn, sock, conn->portal_address,
1982 &conn->portal_port, kernel_getpeername);
1983 if (err)
1984 goto free_socket;
1985
1986 err = iscsi_tcp_get_addr(conn, sock, conn->local_address,
1987 &conn->local_port, kernel_getsockname);
1988 if (err)
1989 goto free_socket;
1932 1990
1933 err = iscsi_conn_bind(cls_session, cls_conn, is_leading); 1991 err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
1934 if (err) 1992 if (err)
1935 return err; 1993 goto free_socket;
1936 1994
1937 /* bind iSCSI connection and socket */ 1995 /* bind iSCSI connection and socket */
1938 tcp_conn->sock = sock; 1996 tcp_conn->sock = sock;
@@ -1956,8 +2014,11 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1956 * set receive state machine into initial state 2014 * set receive state machine into initial state
1957 */ 2015 */
1958 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; 2016 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
1959
1960 return 0; 2017 return 0;
2018
2019free_socket:
2020 sockfd_put(sock);
2021 return err;
1961} 2022}
1962 2023
1963/* called with host lock */ 2024/* called with host lock */
@@ -2077,33 +2138,18 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
2077 enum iscsi_param param, char *buf) 2138 enum iscsi_param param, char *buf)
2078{ 2139{
2079 struct iscsi_conn *conn = cls_conn->dd_data; 2140 struct iscsi_conn *conn = cls_conn->dd_data;
2080 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2081 struct inet_sock *inet;
2082 struct ipv6_pinfo *np;
2083 struct sock *sk;
2084 int len; 2141 int len;
2085 2142
2086 switch(param) { 2143 switch(param) {
2087 case ISCSI_PARAM_CONN_PORT: 2144 case ISCSI_PARAM_CONN_PORT:
2088 if (!tcp_conn->sock) 2145 spin_lock_bh(&conn->session->lock);
2089 return -EINVAL; 2146 len = sprintf(buf, "%hu\n", conn->portal_port);
2090 2147 spin_unlock_bh(&conn->session->lock);
2091 inet = inet_sk(tcp_conn->sock->sk);
2092 len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport));
2093 break; 2148 break;
2094 case ISCSI_PARAM_CONN_ADDRESS: 2149 case ISCSI_PARAM_CONN_ADDRESS:
2095 if (!tcp_conn->sock) 2150 spin_lock_bh(&conn->session->lock);
2096 return -EINVAL; 2151 len = sprintf(buf, "%s\n", conn->portal_address);
2097 2152 spin_unlock_bh(&conn->session->lock);
2098 sk = tcp_conn->sock->sk;
2099 if (sk->sk_family == PF_INET) {
2100 inet = inet_sk(sk);
2101 len = sprintf(buf, NIPQUAD_FMT "\n",
2102 NIPQUAD(inet->daddr));
2103 } else {
2104 np = inet6_sk(sk);
2105 len = sprintf(buf, NIP6_FMT "\n", NIP6(np->daddr));
2106 }
2107 break; 2153 break;
2108 default: 2154 default:
2109 return iscsi_conn_get_param(cls_conn, param, buf); 2155 return iscsi_conn_get_param(cls_conn, param, buf);
@@ -2112,6 +2158,29 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
2112 return len; 2158 return len;
2113} 2159}
2114 2160
2161static int
2162iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
2163 char *buf)
2164{
2165 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
2166 int len;
2167
2168 switch (param) {
2169 case ISCSI_HOST_PARAM_IPADDRESS:
2170 spin_lock_bh(&session->lock);
2171 if (!session->leadconn)
2172 len = -ENODEV;
2173 else
2174 len = sprintf(buf, "%s\n",
2175 session->leadconn->local_address);
2176 spin_unlock_bh(&session->lock);
2177 break;
2178 default:
2179 return iscsi_host_get_param(shost, param, buf);
2180 }
2181 return len;
2182}
2183
2115static void 2184static void
2116iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) 2185iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
2117{ 2186{
@@ -2233,7 +2302,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
2233 ISCSI_TARGET_NAME | ISCSI_TPGT | 2302 ISCSI_TARGET_NAME | ISCSI_TPGT |
2234 ISCSI_USERNAME | ISCSI_PASSWORD | 2303 ISCSI_USERNAME | ISCSI_PASSWORD |
2235 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN, 2304 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,
2236 .host_param_mask = ISCSI_HOST_HWADDRESS | 2305 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
2237 ISCSI_HOST_INITIATOR_NAME, 2306 ISCSI_HOST_INITIATOR_NAME,
2238 .host_template = &iscsi_sht, 2307 .host_template = &iscsi_sht,
2239 .conndata_size = sizeof(struct iscsi_conn), 2308 .conndata_size = sizeof(struct iscsi_conn),
@@ -2252,7 +2321,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
2252 .start_conn = iscsi_conn_start, 2321 .start_conn = iscsi_conn_start,
2253 .stop_conn = iscsi_tcp_conn_stop, 2322 .stop_conn = iscsi_tcp_conn_stop,
2254 /* iscsi host params */ 2323 /* iscsi host params */
2255 .get_host_param = iscsi_host_get_param, 2324 .get_host_param = iscsi_tcp_host_get_param,
2256 .set_host_param = iscsi_host_set_param, 2325 .set_host_param = iscsi_host_set_param,
2257 /* IO */ 2326 /* IO */
2258 .send_pdu = iscsi_conn_send_pdu, 2327 .send_pdu = iscsi_conn_send_pdu,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 315ab691056f..b87b460832ea 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -106,6 +106,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
106 .param_mask = ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS | 106 .param_mask = ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS |
107 ISCSI_TARGET_NAME | ISCSI_TPGT, 107 ISCSI_TARGET_NAME | ISCSI_TPGT,
108 .host_param_mask = ISCSI_HOST_HWADDRESS | 108 .host_param_mask = ISCSI_HOST_HWADDRESS |
109 ISCSI_HOST_IPADDRESS |
109 ISCSI_HOST_INITIATOR_NAME, 110 ISCSI_HOST_INITIATOR_NAME,
110 .sessiondata_size = sizeof(struct ddb_entry), 111 .sessiondata_size = sizeof(struct ddb_entry),
111 .host_template = &qla4xxx_driver_template, 112 .host_template = &qla4xxx_driver_template,
@@ -192,8 +193,13 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
192 case ISCSI_HOST_PARAM_HWADDRESS: 193 case ISCSI_HOST_PARAM_HWADDRESS:
193 len = format_addr(buf, ha->my_mac, MAC_ADDR_LEN); 194 len = format_addr(buf, ha->my_mac, MAC_ADDR_LEN);
194 break; 195 break;
196 case ISCSI_HOST_PARAM_IPADDRESS:
197 len = sprintf(buf, "%d.%d.%d.%d\n", ha->ip_address[0],
198 ha->ip_address[1], ha->ip_address[2],
199 ha->ip_address[3]);
200 break;
195 case ISCSI_HOST_PARAM_INITIATOR_NAME: 201 case ISCSI_HOST_PARAM_INITIATOR_NAME:
196 len = sprintf(buf, ha->name_string); 202 len = sprintf(buf, "%s\n", ha->name_string);
197 break; 203 break;
198 default: 204 default:
199 return -ENOSYS; 205 return -ENOSYS;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 859bd2100856..9b54eea20560 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -32,7 +32,7 @@
32 32
33#define ISCSI_SESSION_ATTRS 15 33#define ISCSI_SESSION_ATTRS 15
34#define ISCSI_CONN_ATTRS 11 34#define ISCSI_CONN_ATTRS 11
35#define ISCSI_HOST_ATTRS 2 35#define ISCSI_HOST_ATTRS 3
36#define ISCSI_TRANSPORT_VERSION "2.0-724" 36#define ISCSI_TRANSPORT_VERSION "2.0-724"
37 37
38struct iscsi_internal { 38struct iscsi_internal {
@@ -1261,6 +1261,7 @@ show_host_param_##param(struct class_device *cdev, char *buf) \
1261static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \ 1261static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \
1262 NULL); 1262 NULL);
1263 1263
1264iscsi_host_attr(ipaddress, ISCSI_HOST_PARAM_IPADDRESS);
1264iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS); 1265iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS);
1265iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME); 1266iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME);
1266 1267
@@ -1398,6 +1399,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
1398 priv->t.host_size = sizeof(struct iscsi_host); 1399 priv->t.host_size = sizeof(struct iscsi_host);
1399 transport_container_register(&priv->t.host_attrs); 1400 transport_container_register(&priv->t.host_attrs);
1400 1401
1402 SETUP_HOST_RD_ATTR(ipaddress, ISCSI_HOST_IPADDRESS);
1401 SETUP_HOST_RD_ATTR(hwaddress, ISCSI_HOST_HWADDRESS); 1403 SETUP_HOST_RD_ATTR(hwaddress, ISCSI_HOST_HWADDRESS);
1402 SETUP_HOST_RD_ATTR(initiatorname, ISCSI_HOST_INITIATOR_NAME); 1404 SETUP_HOST_RD_ATTR(initiatorname, ISCSI_HOST_INITIATOR_NAME);
1403 BUG_ON(count > ISCSI_HOST_ATTRS); 1405 BUG_ON(count > ISCSI_HOST_ATTRS);
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 81a542506dfe..642998069e00 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -271,11 +271,13 @@ enum iscsi_param {
271enum iscsi_host_param { 271enum iscsi_host_param {
272 ISCSI_HOST_PARAM_HWADDRESS, 272 ISCSI_HOST_PARAM_HWADDRESS,
273 ISCSI_HOST_PARAM_INITIATOR_NAME, 273 ISCSI_HOST_PARAM_INITIATOR_NAME,
274 ISCSI_HOST_PARAM_IPADDRESS,
274 ISCSI_HOST_PARAM_MAX, 275 ISCSI_HOST_PARAM_MAX,
275}; 276};
276 277
277#define ISCSI_HOST_HWADDRESS (1 << ISCSI_HOST_PARAM_HWADDRESS) 278#define ISCSI_HOST_HWADDRESS (1 << ISCSI_HOST_PARAM_HWADDRESS)
278#define ISCSI_HOST_INITIATOR_NAME (1 << ISCSI_HOST_PARAM_INITIATOR_NAME) 279#define ISCSI_HOST_INITIATOR_NAME (1 << ISCSI_HOST_PARAM_INITIATOR_NAME)
280#define ISCSI_HOST_IPADDRESS (1 << ISCSI_HOST_PARAM_IPADDRESS)
279 281
280#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) 282#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
281#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) 283#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 2f303a3b270e..eea33f7b1544 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -72,6 +72,8 @@ struct iscsi_nopin;
72#define ISCSI_AGE_SHIFT 28 72#define ISCSI_AGE_SHIFT 28
73#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) 73#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT)
74 74
75#define ISCSI_ADDRESS_BUF_LEN 64
76
75struct iscsi_mgmt_task { 77struct iscsi_mgmt_task {
76 /* 78 /*
77 * Becuae LLDs allocate their hdr differently, this is a pointer to 79 * Becuae LLDs allocate their hdr differently, this is a pointer to
@@ -174,6 +176,12 @@ struct iscsi_conn {
174 /* values userspace uses to id a conn */ 176 /* values userspace uses to id a conn */
175 int persistent_port; 177 int persistent_port;
176 char *persistent_address; 178 char *persistent_address;
179 /* remote portal currently connected to */
180 int portal_port;
181 char portal_address[ISCSI_ADDRESS_BUF_LEN];
182 /* local address */
183 int local_port;
184 char local_address[ISCSI_ADDRESS_BUF_LEN];
177 185
178 /* MIB-statistics */ 186 /* MIB-statistics */
179 uint64_t txdata_octets; 187 uint64_t txdata_octets;