diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index deeb951e6874..a4bc83cbec9e 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -365,6 +365,14 @@ struct ip_addr_format { u16 size_of_structure; u8 reserved; u8 ip_type; +#define BEISCSI_IP_TYPE_V4 0x1 +#define BEISCSI_IP_TYPE_STATIC_V4 0x3 +#define BEISCSI_IP_TYPE_DHCP_V4 0x5 +/* type v4 values < type v6 values */ +#define BEISCSI_IP_TYPE_V6 0x10 +#define BEISCSI_IP_TYPE_ROUTABLE_V6 0x30 +#define BEISCSI_IP_TYPE_LINK_LOCAL_V6 0x50 +#define BEISCSI_IP_TYPE_AUTO_V6 0x90 u8 addr[16]; u32 rsvd0; } __packed; diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index fa415c41ba04..faa37f67a8e6 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -279,12 +279,12 @@ void beiscsi_iface_create_default(struct beiscsi_hba *phba) { struct be_cmd_get_if_info_resp *if_info; - if (!beiscsi_if_get_info(phba, BE2_IPV4, &if_info)) { + if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V4, &if_info)) { beiscsi_iface_create_ipv4(phba); kfree(if_info); } - if (!beiscsi_if_get_info(phba, BE2_IPV6, &if_info)) { + if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V6, &if_info)) { beiscsi_iface_create_ipv6(phba); kfree(if_info); } @@ -358,14 +358,15 @@ beiscsi_iface_config_ipv4(struct Scsi_Host *shost, break; case ISCSI_NET_PARAM_IPV4_GW: gw = info->value; - ret = beiscsi_if_set_gw(phba, BE2_IPV4, gw); + ret = beiscsi_if_set_gw(phba, BEISCSI_IP_TYPE_V4, gw); break; case ISCSI_NET_PARAM_IPV4_BOOTPROTO: if (info->value[0] == ISCSI_BOOTPROTO_DHCP) - ret = beiscsi_if_en_dhcp(phba, BE2_IPV4); + ret = beiscsi_if_en_dhcp(phba, BEISCSI_IP_TYPE_V4); else if (info->value[0] == ISCSI_BOOTPROTO_STATIC) /* release DHCP IP address */ - ret = beiscsi_if_en_static(phba, BE2_IPV4, NULL, NULL); + ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, + NULL, NULL); else beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : Invalid BOOTPROTO: %d\n", @@ -378,7 +379,8 @@ beiscsi_iface_config_ipv4(struct Scsi_Host *shost, info = nla_data(nla); subnet = info->value; } - ret = beiscsi_if_en_static(phba, BE2_IPV4, ip, subnet); + ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, + ip, subnet); break; case ISCSI_NET_PARAM_IPV4_SUBNET: /* @@ -391,7 +393,8 @@ beiscsi_iface_config_ipv4(struct Scsi_Host *shost, info = nla_data(nla); ip = info->value; } - ret = beiscsi_if_en_static(phba, BE2_IPV4, ip, subnet); + ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, + ip, subnet); break; } @@ -416,7 +419,7 @@ beiscsi_iface_config_ipv6(struct Scsi_Host *shost, } break; case ISCSI_NET_PARAM_IPV6_ADDR: - ret = beiscsi_if_en_static(phba, BE2_IPV6, + ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V6, iface_param->value, NULL); break; } @@ -511,10 +514,10 @@ static int __beiscsi_iface_get_param(struct beiscsi_hba *phba, int param, char *buf) { struct be_cmd_get_if_info_resp *if_info; - int len, ip_type = BE2_IPV4; + int len, ip_type = BEISCSI_IP_TYPE_V4; if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) - ip_type = BE2_IPV6; + ip_type = BEISCSI_IP_TYPE_V6; len = beiscsi_if_get_info(phba, ip_type, &if_info); if (len) @@ -602,7 +605,7 @@ int beiscsi_iface_get_param(struct iscsi_iface *iface, break; case ISCSI_NET_PARAM_IPV4_GW: memset(&gateway, 0, sizeof(gateway)); - len = beiscsi_if_get_gw(phba, BE2_IPV4, &gateway); + len = beiscsi_if_get_gw(phba, BEISCSI_IP_TYPE_V4, &gateway); if (!len) len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); break; @@ -635,7 +638,7 @@ int beiscsi_ep_get_param(struct iscsi_endpoint *ep, len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport); break; case ISCSI_PARAM_CONN_ADDRESS: - if (beiscsi_ep->ip_type == BE2_IPV4) + if (beiscsi_ep->ip_type == BEISCSI_IP_TYPE_V4) len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr); else len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr); diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index 5928ba9d8918..0089e67badf8 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h @@ -23,13 +23,6 @@ #include "be_main.h" #include "be_mgmt.h" -#define BE2_IPV4 0x1 -#define BE2_IPV6 0x10 -#define BE2_DHCP_V4 0x05 - -#define NON_BLOCKING 0x0 -#define BLOCKING 0x1 - void beiscsi_iface_create_default(struct beiscsi_hba *phba); void beiscsi_iface_destroy_default(struct beiscsi_hba *phba); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 71c91314d4c9..0fbb80d3e090 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -389,7 +389,7 @@ static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf) (char *)&boot_sess->target_name); break; case ISCSI_BOOT_TGT_IP_ADDR: - if (boot_conn->dest_ipaddr.ip_type == 0x1) + if (boot_conn->dest_ipaddr.ip_type == BEISCSI_IP_TYPE_V4) rc = sprintf(buf, "%pI4\n", (char *)&boot_conn->dest_ipaddr.addr); else diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 8d05add812c4..8069ef0ce533 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -844,7 +844,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, nonemb_cmd->size); if (dst_addr->sa_family == PF_INET) { __be32 s_addr = daddr_in->sin_addr.s_addr; - req->ip_address.ip_type = BE2_IPV4; + req->ip_address.ip_type = BEISCSI_IP_TYPE_V4; req->ip_address.addr[0] = s_addr & 0x000000ff; req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8; req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16; @@ -852,17 +852,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba, req->tcp_port = ntohs(daddr_in->sin_port); beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr; beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port); - beiscsi_ep->ip_type = BE2_IPV4; + beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4; } else { /* else its PF_INET6 family */ - req->ip_address.ip_type = BE2_IPV6; + req->ip_address.ip_type = BEISCSI_IP_TYPE_V6; memcpy(&req->ip_address.addr, &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); req->tcp_port = ntohs(daddr_in6->sin6_port); beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port); memcpy(&beiscsi_ep->dst6_addr, &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); - beiscsi_ep->ip_type = BE2_IPV6; + beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6; } req->cid = cid; i = phba->nxt_cqid++; @@ -1008,6 +1008,16 @@ unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba) return status; } +static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type) +{ + u32 len; + + len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN; + while (len && !ip[len - 1]) + len--; + return (len == 0); +} + static int beiscsi_if_mod_gw(struct beiscsi_hba *phba, u32 action, u32 ip_type, u8 *gw) { @@ -1025,7 +1035,7 @@ static int beiscsi_if_mod_gw(struct beiscsi_hba *phba, req->action = action; req->ip_addr.ip_type = ip_type; memcpy(req->ip_addr.addr, gw, - (ip_type == BE2_IPV4) ? IP_V4_LEN : IP_V6_LEN); + (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN); return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); } @@ -1042,12 +1052,14 @@ int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw) return rt_val; } - rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type, - gw_resp.ip_addr.addr); - if (rt_val) { - beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, - "BG_%d : Failed to clear Gateway Addr Set\n"); - return rt_val; + if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) { + rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type, + gw_resp.ip_addr.addr); + if (rt_val) { + beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, + "BG_%d : Failed to clear Gateway Addr Set\n"); + return rt_val; + } } rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw); @@ -1138,7 +1150,7 @@ beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip, req->ip_params.ip_record.ip_addr.size_of_structure = sizeof(struct be_ip_addr_subnet_format); req->ip_params.ip_record.ip_addr.ip_type = ip_type; - ip_len = ip_type == BE2_IPV4 ? IP_V4_LEN : IP_V6_LEN; + ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN; memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len); if (subnet) memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, @@ -1190,10 +1202,12 @@ int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type, } } - /* first delete any old IP set */ - rc = beiscsi_if_clr_ip(phba, if_info); - if (rc) - goto exit; + /* first delete any IP set */ + if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) { + rc = beiscsi_if_clr_ip(phba, if_info); + if (rc) + goto exit; + } /* if ip == NULL then this is called just to release DHCP IP */ if (ip) @@ -1222,10 +1236,12 @@ int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type) goto exit; } - /* first delete any old static IP set */ - rc = beiscsi_if_clr_ip(phba, if_info); - if (rc) - goto exit; + /* first delete any IP set */ + if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) { + rc = beiscsi_if_clr_ip(phba, if_info); + if (rc) + goto exit; + } /* delete gateway settings if mode change is to DHCP */ memset(&gw_resp, 0, sizeof(gw_resp)); @@ -1237,12 +1253,14 @@ int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type) goto exit; } gw = (u8 *)&gw_resp.ip_addr.addr; - rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, - if_info->ip_addr.ip_type, gw); - if (rc) { - beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, - "BG_%d : Failed to clear Gateway Addr Set\n"); - goto exit; + if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) { + rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, + if_info->ip_addr.ip_type, gw); + if (rc) { + beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, + "BG_%d : Failed to clear Gateway Addr Set\n"); + goto exit; + } } rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, @@ -1252,7 +1270,7 @@ int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type) goto exit; dhcpreq = nonemb_cmd.va; - dhcpreq->flags = BLOCKING; + dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */ dhcpreq->retry_count = 1; dhcpreq->interface_hndl = phba->interface_handle; dhcpreq->ip_type = ip_type;