Merge branch 'master' into for-next
[cascardo/linux.git] / drivers / scsi / scsi_transport_iscsi.c
index de5b4d9..0102a2d 100644 (file)
@@ -305,20 +305,71 @@ show_##type##_##name(struct device *dev, struct device_attribute *attr,   \
        iscsi_iface_attr_show(type, name, ISCSI_NET_PARAM, param)       \
 static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
 
-/* generic read only ipvi4 attribute */
+#define iscsi_iface_attr(type, name, param)                            \
+       iscsi_iface_attr_show(type, name, ISCSI_IFACE_PARAM, param)     \
+static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
+
+/* generic read only ipv4 attribute */
 iscsi_iface_net_attr(ipv4_iface, ipaddress, ISCSI_NET_PARAM_IPV4_ADDR);
 iscsi_iface_net_attr(ipv4_iface, gateway, ISCSI_NET_PARAM_IPV4_GW);
 iscsi_iface_net_attr(ipv4_iface, subnet, ISCSI_NET_PARAM_IPV4_SUBNET);
 iscsi_iface_net_attr(ipv4_iface, bootproto, ISCSI_NET_PARAM_IPV4_BOOTPROTO);
+iscsi_iface_net_attr(ipv4_iface, dhcp_dns_address_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_slp_da_info_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN);
+iscsi_iface_net_attr(ipv4_iface, tos_en, ISCSI_NET_PARAM_IPV4_TOS_EN);
+iscsi_iface_net_attr(ipv4_iface, tos, ISCSI_NET_PARAM_IPV4_TOS);
+iscsi_iface_net_attr(ipv4_iface, grat_arp_en,
+                    ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_alt_client_id_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_alt_client_id,
+                    ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID);
+iscsi_iface_net_attr(ipv4_iface, dhcp_req_vendor_id_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_use_vendor_id_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_vendor_id,
+                    ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID);
+iscsi_iface_net_attr(ipv4_iface, dhcp_learn_iqn_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN);
+iscsi_iface_net_attr(ipv4_iface, fragment_disable,
+                    ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE);
+iscsi_iface_net_attr(ipv4_iface, incoming_forwarding_en,
+                    ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN);
+iscsi_iface_net_attr(ipv4_iface, ttl, ISCSI_NET_PARAM_IPV4_TTL);
 
 /* generic read only ipv6 attribute */
 iscsi_iface_net_attr(ipv6_iface, ipaddress, ISCSI_NET_PARAM_IPV6_ADDR);
-iscsi_iface_net_attr(ipv6_iface, link_local_addr, ISCSI_NET_PARAM_IPV6_LINKLOCAL);
+iscsi_iface_net_attr(ipv6_iface, link_local_addr,
+                    ISCSI_NET_PARAM_IPV6_LINKLOCAL);
 iscsi_iface_net_attr(ipv6_iface, router_addr, ISCSI_NET_PARAM_IPV6_ROUTER);
 iscsi_iface_net_attr(ipv6_iface, ipaddr_autocfg,
                     ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG);
 iscsi_iface_net_attr(ipv6_iface, link_local_autocfg,
                     ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG);
+iscsi_iface_net_attr(ipv6_iface, link_local_state,
+                    ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE);
+iscsi_iface_net_attr(ipv6_iface, router_state,
+                    ISCSI_NET_PARAM_IPV6_ROUTER_STATE);
+iscsi_iface_net_attr(ipv6_iface, grat_neighbor_adv_en,
+                    ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN);
+iscsi_iface_net_attr(ipv6_iface, mld_en, ISCSI_NET_PARAM_IPV6_MLD_EN);
+iscsi_iface_net_attr(ipv6_iface, flow_label, ISCSI_NET_PARAM_IPV6_FLOW_LABEL);
+iscsi_iface_net_attr(ipv6_iface, traffic_class,
+                    ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS);
+iscsi_iface_net_attr(ipv6_iface, hop_limit, ISCSI_NET_PARAM_IPV6_HOP_LIMIT);
+iscsi_iface_net_attr(ipv6_iface, nd_reachable_tmo,
+                    ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO);
+iscsi_iface_net_attr(ipv6_iface, nd_rexmit_time,
+                    ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME);
+iscsi_iface_net_attr(ipv6_iface, nd_stale_tmo,
+                    ISCSI_NET_PARAM_IPV6_ND_STALE_TMO);
+iscsi_iface_net_attr(ipv6_iface, dup_addr_detect_cnt,
+                    ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT);
+iscsi_iface_net_attr(ipv6_iface, router_adv_link_mtu,
+                    ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU);
 
 /* common read only iface attribute */
 iscsi_iface_net_attr(iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLE);
@@ -327,6 +378,40 @@ iscsi_iface_net_attr(iface, vlan_priority, ISCSI_NET_PARAM_VLAN_PRIORITY);
 iscsi_iface_net_attr(iface, vlan_enabled, ISCSI_NET_PARAM_VLAN_ENABLED);
 iscsi_iface_net_attr(iface, mtu, ISCSI_NET_PARAM_MTU);
 iscsi_iface_net_attr(iface, port, ISCSI_NET_PARAM_PORT);
+iscsi_iface_net_attr(iface, ipaddress_state, ISCSI_NET_PARAM_IPADDR_STATE);
+iscsi_iface_net_attr(iface, delayed_ack_en, ISCSI_NET_PARAM_DELAYED_ACK_EN);
+iscsi_iface_net_attr(iface, tcp_nagle_disable,
+                    ISCSI_NET_PARAM_TCP_NAGLE_DISABLE);
+iscsi_iface_net_attr(iface, tcp_wsf_disable, ISCSI_NET_PARAM_TCP_WSF_DISABLE);
+iscsi_iface_net_attr(iface, tcp_wsf, ISCSI_NET_PARAM_TCP_WSF);
+iscsi_iface_net_attr(iface, tcp_timer_scale, ISCSI_NET_PARAM_TCP_TIMER_SCALE);
+iscsi_iface_net_attr(iface, tcp_timestamp_en, ISCSI_NET_PARAM_TCP_TIMESTAMP_EN);
+iscsi_iface_net_attr(iface, cache_id, ISCSI_NET_PARAM_CACHE_ID);
+iscsi_iface_net_attr(iface, redirect_en, ISCSI_NET_PARAM_REDIRECT_EN);
+
+/* common iscsi specific settings attributes */
+iscsi_iface_attr(iface, def_taskmgmt_tmo, ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO);
+iscsi_iface_attr(iface, header_digest, ISCSI_IFACE_PARAM_HDRDGST_EN);
+iscsi_iface_attr(iface, data_digest, ISCSI_IFACE_PARAM_DATADGST_EN);
+iscsi_iface_attr(iface, immediate_data, ISCSI_IFACE_PARAM_IMM_DATA_EN);
+iscsi_iface_attr(iface, initial_r2t, ISCSI_IFACE_PARAM_INITIAL_R2T_EN);
+iscsi_iface_attr(iface, data_seq_in_order,
+                ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN);
+iscsi_iface_attr(iface, data_pdu_in_order, ISCSI_IFACE_PARAM_PDU_INORDER_EN);
+iscsi_iface_attr(iface, erl, ISCSI_IFACE_PARAM_ERL);
+iscsi_iface_attr(iface, max_recv_dlength, ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH);
+iscsi_iface_attr(iface, first_burst_len, ISCSI_IFACE_PARAM_FIRST_BURST);
+iscsi_iface_attr(iface, max_outstanding_r2t, ISCSI_IFACE_PARAM_MAX_R2T);
+iscsi_iface_attr(iface, max_burst_len, ISCSI_IFACE_PARAM_MAX_BURST);
+iscsi_iface_attr(iface, chap_auth, ISCSI_IFACE_PARAM_CHAP_AUTH_EN);
+iscsi_iface_attr(iface, bidi_chap, ISCSI_IFACE_PARAM_BIDI_CHAP_EN);
+iscsi_iface_attr(iface, discovery_auth_optional,
+                ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL);
+iscsi_iface_attr(iface, discovery_logout,
+                ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN);
+iscsi_iface_attr(iface, strict_login_comp_en,
+                ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN);
+iscsi_iface_attr(iface, initiator_name, ISCSI_IFACE_PARAM_INITIATOR_NAME);
 
 static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                                          struct attribute *attr, int i)
@@ -335,6 +420,7 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
        struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
        struct iscsi_transport *t = iface->transport;
        int param;
+       int param_type;
 
        if (attr == &dev_attr_iface_enabled.attr)
                param = ISCSI_NET_PARAM_IFACE_ENABLE;
@@ -348,6 +434,60 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                param = ISCSI_NET_PARAM_MTU;
        else if (attr == &dev_attr_iface_port.attr)
                param = ISCSI_NET_PARAM_PORT;
+       else if (attr == &dev_attr_iface_ipaddress_state.attr)
+               param = ISCSI_NET_PARAM_IPADDR_STATE;
+       else if (attr == &dev_attr_iface_delayed_ack_en.attr)
+               param = ISCSI_NET_PARAM_DELAYED_ACK_EN;
+       else if (attr == &dev_attr_iface_tcp_nagle_disable.attr)
+               param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE;
+       else if (attr == &dev_attr_iface_tcp_wsf_disable.attr)
+               param = ISCSI_NET_PARAM_TCP_WSF_DISABLE;
+       else if (attr == &dev_attr_iface_tcp_wsf.attr)
+               param = ISCSI_NET_PARAM_TCP_WSF;
+       else if (attr == &dev_attr_iface_tcp_timer_scale.attr)
+               param = ISCSI_NET_PARAM_TCP_TIMER_SCALE;
+       else if (attr == &dev_attr_iface_tcp_timestamp_en.attr)
+               param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN;
+       else if (attr == &dev_attr_iface_cache_id.attr)
+               param = ISCSI_NET_PARAM_CACHE_ID;
+       else if (attr == &dev_attr_iface_redirect_en.attr)
+               param = ISCSI_NET_PARAM_REDIRECT_EN;
+       else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr)
+               param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO;
+       else if (attr == &dev_attr_iface_header_digest.attr)
+               param = ISCSI_IFACE_PARAM_HDRDGST_EN;
+       else if (attr == &dev_attr_iface_data_digest.attr)
+               param = ISCSI_IFACE_PARAM_DATADGST_EN;
+       else if (attr == &dev_attr_iface_immediate_data.attr)
+               param = ISCSI_IFACE_PARAM_IMM_DATA_EN;
+       else if (attr == &dev_attr_iface_initial_r2t.attr)
+               param = ISCSI_IFACE_PARAM_INITIAL_R2T_EN;
+       else if (attr == &dev_attr_iface_data_seq_in_order.attr)
+               param = ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN;
+       else if (attr == &dev_attr_iface_data_pdu_in_order.attr)
+               param = ISCSI_IFACE_PARAM_PDU_INORDER_EN;
+       else if (attr == &dev_attr_iface_erl.attr)
+               param = ISCSI_IFACE_PARAM_ERL;
+       else if (attr == &dev_attr_iface_max_recv_dlength.attr)
+               param = ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH;
+       else if (attr == &dev_attr_iface_first_burst_len.attr)
+               param = ISCSI_IFACE_PARAM_FIRST_BURST;
+       else if (attr == &dev_attr_iface_max_outstanding_r2t.attr)
+               param = ISCSI_IFACE_PARAM_MAX_R2T;
+       else if (attr == &dev_attr_iface_max_burst_len.attr)
+               param = ISCSI_IFACE_PARAM_MAX_BURST;
+       else if (attr == &dev_attr_iface_chap_auth.attr)
+               param = ISCSI_IFACE_PARAM_CHAP_AUTH_EN;
+       else if (attr == &dev_attr_iface_bidi_chap.attr)
+               param = ISCSI_IFACE_PARAM_BIDI_CHAP_EN;
+       else if (attr == &dev_attr_iface_discovery_auth_optional.attr)
+               param = ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL;
+       else if (attr == &dev_attr_iface_discovery_logout.attr)
+               param = ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN;
+       else if (attr == &dev_attr_iface_strict_login_comp_en.attr)
+               param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN;
+       else if (attr == &dev_attr_iface_initiator_name.attr)
+               param = ISCSI_IFACE_PARAM_INITIATOR_NAME;
        else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
                if (attr == &dev_attr_ipv4_iface_ipaddress.attr)
                        param = ISCSI_NET_PARAM_IPV4_ADDR;
@@ -357,6 +497,42 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                        param = ISCSI_NET_PARAM_IPV4_SUBNET;
                else if (attr == &dev_attr_ipv4_iface_bootproto.attr)
                        param = ISCSI_NET_PARAM_IPV4_BOOTPROTO;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_dns_address_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_slp_da_info_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN;
+               else if (attr == &dev_attr_ipv4_iface_tos_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_TOS_EN;
+               else if (attr == &dev_attr_ipv4_iface_tos.attr)
+                       param = ISCSI_NET_PARAM_IPV4_TOS;
+               else if (attr == &dev_attr_ipv4_iface_grat_arp_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_alt_client_id_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN;
+               else if (attr == &dev_attr_ipv4_iface_dhcp_alt_client_id.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_req_vendor_id_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_use_vendor_id_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN;
+               else if (attr == &dev_attr_ipv4_iface_dhcp_vendor_id.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_learn_iqn_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_fragment_disable.attr)
+                       param = ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_incoming_forwarding_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN;
+               else if (attr == &dev_attr_ipv4_iface_ttl.attr)
+                       param = ISCSI_NET_PARAM_IPV4_TTL;
                else
                        return 0;
        } else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) {
@@ -370,6 +546,31 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                        param = ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG;
                else if (attr == &dev_attr_ipv6_iface_link_local_autocfg.attr)
                        param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG;
+               else if (attr == &dev_attr_ipv6_iface_link_local_state.attr)
+                       param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE;
+               else if (attr == &dev_attr_ipv6_iface_router_state.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ROUTER_STATE;
+               else if (attr ==
+                        &dev_attr_ipv6_iface_grat_neighbor_adv_en.attr)
+                       param = ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN;
+               else if (attr == &dev_attr_ipv6_iface_mld_en.attr)
+                       param = ISCSI_NET_PARAM_IPV6_MLD_EN;
+               else if (attr == &dev_attr_ipv6_iface_flow_label.attr)
+                       param = ISCSI_NET_PARAM_IPV6_FLOW_LABEL;
+               else if (attr == &dev_attr_ipv6_iface_traffic_class.attr)
+                       param = ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS;
+               else if (attr == &dev_attr_ipv6_iface_hop_limit.attr)
+                       param = ISCSI_NET_PARAM_IPV6_HOP_LIMIT;
+               else if (attr == &dev_attr_ipv6_iface_nd_reachable_tmo.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO;
+               else if (attr == &dev_attr_ipv6_iface_nd_rexmit_time.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME;
+               else if (attr == &dev_attr_ipv6_iface_nd_stale_tmo.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ND_STALE_TMO;
+               else if (attr == &dev_attr_ipv6_iface_dup_addr_detect_cnt.attr)
+                       param = ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT;
+               else if (attr == &dev_attr_ipv6_iface_router_adv_link_mtu.attr)
+                       param = ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU;
                else
                        return 0;
        } else {
@@ -377,7 +578,32 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                return 0;
        }
 
-       return t->attr_is_visible(ISCSI_NET_PARAM, param);
+       switch (param) {
+       case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:
+       case ISCSI_IFACE_PARAM_HDRDGST_EN:
+       case ISCSI_IFACE_PARAM_DATADGST_EN:
+       case ISCSI_IFACE_PARAM_IMM_DATA_EN:
+       case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:
+       case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:
+       case ISCSI_IFACE_PARAM_PDU_INORDER_EN:
+       case ISCSI_IFACE_PARAM_ERL:
+       case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:
+       case ISCSI_IFACE_PARAM_FIRST_BURST:
+       case ISCSI_IFACE_PARAM_MAX_R2T:
+       case ISCSI_IFACE_PARAM_MAX_BURST:
+       case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:
+       case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:
+       case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:
+       case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:
+       case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:
+       case ISCSI_IFACE_PARAM_INITIATOR_NAME:
+               param_type = ISCSI_IFACE_PARAM;
+               break;
+       default:
+               param_type = ISCSI_NET_PARAM;
+       }
+
+       return t->attr_is_visible(param_type, param);
 }
 
 static struct attribute *iscsi_iface_attrs[] = {
@@ -396,6 +622,59 @@ static struct attribute *iscsi_iface_attrs[] = {
        &dev_attr_ipv6_iface_link_local_autocfg.attr,
        &dev_attr_iface_mtu.attr,
        &dev_attr_iface_port.attr,
+       &dev_attr_iface_ipaddress_state.attr,
+       &dev_attr_iface_delayed_ack_en.attr,
+       &dev_attr_iface_tcp_nagle_disable.attr,
+       &dev_attr_iface_tcp_wsf_disable.attr,
+       &dev_attr_iface_tcp_wsf.attr,
+       &dev_attr_iface_tcp_timer_scale.attr,
+       &dev_attr_iface_tcp_timestamp_en.attr,
+       &dev_attr_iface_cache_id.attr,
+       &dev_attr_iface_redirect_en.attr,
+       &dev_attr_iface_def_taskmgmt_tmo.attr,
+       &dev_attr_iface_header_digest.attr,
+       &dev_attr_iface_data_digest.attr,
+       &dev_attr_iface_immediate_data.attr,
+       &dev_attr_iface_initial_r2t.attr,
+       &dev_attr_iface_data_seq_in_order.attr,
+       &dev_attr_iface_data_pdu_in_order.attr,
+       &dev_attr_iface_erl.attr,
+       &dev_attr_iface_max_recv_dlength.attr,
+       &dev_attr_iface_first_burst_len.attr,
+       &dev_attr_iface_max_outstanding_r2t.attr,
+       &dev_attr_iface_max_burst_len.attr,
+       &dev_attr_iface_chap_auth.attr,
+       &dev_attr_iface_bidi_chap.attr,
+       &dev_attr_iface_discovery_auth_optional.attr,
+       &dev_attr_iface_discovery_logout.attr,
+       &dev_attr_iface_strict_login_comp_en.attr,
+       &dev_attr_iface_initiator_name.attr,
+       &dev_attr_ipv4_iface_dhcp_dns_address_en.attr,
+       &dev_attr_ipv4_iface_dhcp_slp_da_info_en.attr,
+       &dev_attr_ipv4_iface_tos_en.attr,
+       &dev_attr_ipv4_iface_tos.attr,
+       &dev_attr_ipv4_iface_grat_arp_en.attr,
+       &dev_attr_ipv4_iface_dhcp_alt_client_id_en.attr,
+       &dev_attr_ipv4_iface_dhcp_alt_client_id.attr,
+       &dev_attr_ipv4_iface_dhcp_req_vendor_id_en.attr,
+       &dev_attr_ipv4_iface_dhcp_use_vendor_id_en.attr,
+       &dev_attr_ipv4_iface_dhcp_vendor_id.attr,
+       &dev_attr_ipv4_iface_dhcp_learn_iqn_en.attr,
+       &dev_attr_ipv4_iface_fragment_disable.attr,
+       &dev_attr_ipv4_iface_incoming_forwarding_en.attr,
+       &dev_attr_ipv4_iface_ttl.attr,
+       &dev_attr_ipv6_iface_link_local_state.attr,
+       &dev_attr_ipv6_iface_router_state.attr,
+       &dev_attr_ipv6_iface_grat_neighbor_adv_en.attr,
+       &dev_attr_ipv6_iface_mld_en.attr,
+       &dev_attr_ipv6_iface_flow_label.attr,
+       &dev_attr_ipv6_iface_traffic_class.attr,
+       &dev_attr_ipv6_iface_hop_limit.attr,
+       &dev_attr_ipv6_iface_nd_reachable_tmo.attr,
+       &dev_attr_ipv6_iface_nd_rexmit_time.attr,
+       &dev_attr_ipv6_iface_nd_stale_tmo.attr,
+       &dev_attr_ipv6_iface_dup_addr_detect_cnt.attr,
+       &dev_attr_ipv6_iface_router_adv_link_mtu.attr,
        NULL,
 };
 
@@ -404,6 +683,61 @@ static struct attribute_group iscsi_iface_group = {
        .is_visible = iscsi_iface_attr_is_visible,
 };
 
+/* convert iscsi_ipaddress_state values to ascii string name */
+static const struct {
+       enum iscsi_ipaddress_state      value;
+       char                            *name;
+} iscsi_ipaddress_state_names[] = {
+       {ISCSI_IPDDRESS_STATE_UNCONFIGURED,     "Unconfigured" },
+       {ISCSI_IPDDRESS_STATE_ACQUIRING,        "Acquiring" },
+       {ISCSI_IPDDRESS_STATE_TENTATIVE,        "Tentative" },
+       {ISCSI_IPDDRESS_STATE_VALID,            "Valid" },
+       {ISCSI_IPDDRESS_STATE_DISABLING,        "Disabling" },
+       {ISCSI_IPDDRESS_STATE_INVALID,          "Invalid" },
+       {ISCSI_IPDDRESS_STATE_DEPRECATED,       "Deprecated" },
+};
+
+char *iscsi_get_ipaddress_state_name(enum iscsi_ipaddress_state port_state)
+{
+       int i;
+       char *state = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(iscsi_ipaddress_state_names); i++) {
+               if (iscsi_ipaddress_state_names[i].value == port_state) {
+                       state = iscsi_ipaddress_state_names[i].name;
+                       break;
+               }
+       }
+       return state;
+}
+EXPORT_SYMBOL_GPL(iscsi_get_ipaddress_state_name);
+
+/* convert iscsi_router_state values to ascii string name */
+static const struct {
+       enum iscsi_router_state value;
+       char                    *name;
+} iscsi_router_state_names[] = {
+       {ISCSI_ROUTER_STATE_UNKNOWN,            "Unknown" },
+       {ISCSI_ROUTER_STATE_ADVERTISED,         "Advertised" },
+       {ISCSI_ROUTER_STATE_MANUAL,             "Manual" },
+       {ISCSI_ROUTER_STATE_STALE,              "Stale" },
+};
+
+char *iscsi_get_router_state_name(enum iscsi_router_state router_state)
+{
+       int i;
+       char *state = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(iscsi_router_state_names); i++) {
+               if (iscsi_router_state_names[i].value == router_state) {
+                       state = iscsi_router_state_names[i].name;
+                       break;
+               }
+       }
+       return state;
+}
+EXPORT_SYMBOL_GPL(iscsi_get_router_state_name);
+
 struct iscsi_iface *
 iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
                   uint32_t iface_type, uint32_t iface_num, int dd_size)
@@ -3081,6 +3415,73 @@ exit_logout_sid:
        return err;
 }
 
+static int
+iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
+{
+       struct iscsi_uevent *ev = nlmsg_data(nlh);
+       struct Scsi_Host *shost = NULL;
+       struct iscsi_internal *priv;
+       struct sk_buff *skbhost_stats;
+       struct nlmsghdr *nlhhost_stats;
+       struct iscsi_uevent *evhost_stats;
+       int host_stats_size = 0;
+       int len, err = 0;
+       char *buf;
+
+       if (!transport->get_host_stats)
+               return -EINVAL;
+
+       priv = iscsi_if_transport_lookup(transport);
+       if (!priv)
+               return -EINVAL;
+
+       host_stats_size = sizeof(struct iscsi_offload_host_stats);
+       len = nlmsg_total_size(sizeof(*ev) + host_stats_size);
+
+       shost = scsi_host_lookup(ev->u.get_host_stats.host_no);
+       if (!shost) {
+               pr_err("%s: failed. Cound not find host no %u\n",
+                      __func__, ev->u.get_host_stats.host_no);
+               return -ENODEV;
+       }
+
+       do {
+               int actual_size;
+
+               skbhost_stats = alloc_skb(len, GFP_KERNEL);
+               if (!skbhost_stats) {
+                       pr_err("cannot deliver host stats: OOM\n");
+                       err = -ENOMEM;
+                       goto exit_host_stats;
+               }
+
+               nlhhost_stats = __nlmsg_put(skbhost_stats, 0, 0, 0,
+                                     (len - sizeof(*nlhhost_stats)), 0);
+               evhost_stats = nlmsg_data(nlhhost_stats);
+               memset(evhost_stats, 0, sizeof(*evhost_stats));
+               evhost_stats->transport_handle = iscsi_handle(transport);
+               evhost_stats->type = nlh->nlmsg_type;
+               evhost_stats->u.get_host_stats.host_no =
+                                       ev->u.get_host_stats.host_no;
+               buf = (char *)((char *)evhost_stats + sizeof(*evhost_stats));
+               memset(buf, 0, host_stats_size);
+
+               err = transport->get_host_stats(shost, buf, host_stats_size);
+
+               actual_size = nlmsg_total_size(sizeof(*ev) + host_stats_size);
+               skb_trim(skbhost_stats, NLMSG_ALIGN(actual_size));
+               nlhhost_stats->nlmsg_len = actual_size;
+
+               err = iscsi_multicast_skb(skbhost_stats, ISCSI_NL_GRP_ISCSID,
+                                         GFP_KERNEL);
+       } while (err < 0 && err != -ECONNREFUSED);
+
+exit_host_stats:
+       scsi_host_put(shost);
+       return err;
+}
+
+
 static int
 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 {
@@ -3260,6 +3661,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
                err = iscsi_set_chap(transport, ev,
                                     nlmsg_attrlen(nlh, sizeof(*ev)));
                break;
+       case ISCSI_UEVENT_GET_HOST_STATS:
+               err = iscsi_get_host_stats(transport, nlh);
+               break;
        default:
                err = -ENOSYS;
                break;
@@ -3368,6 +3772,7 @@ iscsi_conn_attr(ipv6_flow_label, ISCSI_PARAM_IPV6_FLOW_LABEL);
 iscsi_conn_attr(is_fw_assigned_ipv6, ISCSI_PARAM_IS_FW_ASSIGNED_IPV6);
 iscsi_conn_attr(tcp_xmit_wsf, ISCSI_PARAM_TCP_XMIT_WSF);
 iscsi_conn_attr(tcp_recv_wsf, ISCSI_PARAM_TCP_RECV_WSF);
+iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR);
 
 
 #define iscsi_conn_ep_attr_show(param)                                 \
@@ -3437,6 +3842,7 @@ static struct attribute *iscsi_conn_attrs[] = {
        &dev_attr_conn_is_fw_assigned_ipv6.attr,
        &dev_attr_conn_tcp_xmit_wsf.attr,
        &dev_attr_conn_tcp_recv_wsf.attr,
+       &dev_attr_conn_local_ipaddr.attr,
        NULL,
 };
 
@@ -3506,6 +3912,8 @@ static umode_t iscsi_conn_attr_is_visible(struct kobject *kobj,
                param = ISCSI_PARAM_TCP_XMIT_WSF;
        else if (attr == &dev_attr_conn_tcp_recv_wsf.attr)
                param = ISCSI_PARAM_TCP_RECV_WSF;
+       else if (attr == &dev_attr_conn_local_ipaddr.attr)
+               param = ISCSI_PARAM_LOCAL_IPADDR;
        else {
                WARN_ONCE(1, "Invalid conn attr");
                return 0;