Commit e48b9eaa authored by Ursula Braun's avatar Ursula Braun Committed by David S. Miller

s390/qeth: fix retrieval of vipa and proxy-arp addresses

qeth devices in layer3 mode need a separate handling of vipa and proxy-arp
addresses. vipa and proxy-arp addresses processed by qeth can be read from
userspace. Introduced with commit 5f78e29c ("qeth: optimize IP handling
in rx_mode callback") the retrieval of vipa and proxy-arp addresses is
broken, if more than one vipa or proxy-arp address are set.

The qeth code used local variable "int i" for 2 different purposes. This
patch now spends 2 separate local variables of type "int".
While touching these functions hash_for_each_safe() is converted to
hash_for_each(), since there is no removal of hash entries.
Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: default avatarJulian Wiedmann <jwi@linux.vnet.ibm.com>
Reference-ID: RQM 3524
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 10340510
...@@ -689,15 +689,15 @@ static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card, ...@@ -689,15 +689,15 @@ static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto) enum qeth_prot_versions proto)
{ {
struct qeth_ipaddr *ipaddr; struct qeth_ipaddr *ipaddr;
struct hlist_node *tmp;
char addr_str[40]; char addr_str[40];
int str_len = 0;
int entry_len; /* length of 1 entry string, differs between v4 and v6 */ int entry_len; /* length of 1 entry string, differs between v4 and v6 */
int i = 0; int i;
entry_len = (proto == QETH_PROT_IPV4)? 12 : 40; entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
entry_len += 2; /* \n + terminator */ entry_len += 2; /* \n + terminator */
spin_lock_bh(&card->ip_lock); spin_lock_bh(&card->ip_lock);
hash_for_each_safe(card->ip_htable, i, tmp, ipaddr, hnode) { hash_for_each(card->ip_htable, i, ipaddr, hnode) {
if (ipaddr->proto != proto) if (ipaddr->proto != proto)
continue; continue;
if (ipaddr->type != QETH_IP_TYPE_VIPA) if (ipaddr->type != QETH_IP_TYPE_VIPA)
...@@ -705,16 +705,17 @@ static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card, ...@@ -705,16 +705,17 @@ static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
/* String must not be longer than PAGE_SIZE. So we check if /* String must not be longer than PAGE_SIZE. So we check if
* string length gets near PAGE_SIZE. Then we can savely display * string length gets near PAGE_SIZE. Then we can savely display
* the next IPv6 address (worst case, compared to IPv4) */ * the next IPv6 address (worst case, compared to IPv4) */
if ((PAGE_SIZE - i) <= entry_len) if ((PAGE_SIZE - str_len) <= entry_len)
break; break;
qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u, qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
addr_str); addr_str);
i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str); str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "%s\n",
addr_str);
} }
spin_unlock_bh(&card->ip_lock); spin_unlock_bh(&card->ip_lock);
i += snprintf(buf + i, PAGE_SIZE - i, "\n"); str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "\n");
return i; return str_len;
} }
static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev, static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
...@@ -851,15 +852,15 @@ static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card, ...@@ -851,15 +852,15 @@ static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto) enum qeth_prot_versions proto)
{ {
struct qeth_ipaddr *ipaddr; struct qeth_ipaddr *ipaddr;
struct hlist_node *tmp;
char addr_str[40]; char addr_str[40];
int str_len = 0;
int entry_len; /* length of 1 entry string, differs between v4 and v6 */ int entry_len; /* length of 1 entry string, differs between v4 and v6 */
int i = 0; int i;
entry_len = (proto == QETH_PROT_IPV4)? 12 : 40; entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
entry_len += 2; /* \n + terminator */ entry_len += 2; /* \n + terminator */
spin_lock_bh(&card->ip_lock); spin_lock_bh(&card->ip_lock);
hash_for_each_safe(card->ip_htable, i, tmp, ipaddr, hnode) { hash_for_each(card->ip_htable, i, ipaddr, hnode) {
if (ipaddr->proto != proto) if (ipaddr->proto != proto)
continue; continue;
if (ipaddr->type != QETH_IP_TYPE_RXIP) if (ipaddr->type != QETH_IP_TYPE_RXIP)
...@@ -867,16 +868,17 @@ static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card, ...@@ -867,16 +868,17 @@ static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
/* String must not be longer than PAGE_SIZE. So we check if /* String must not be longer than PAGE_SIZE. So we check if
* string length gets near PAGE_SIZE. Then we can savely display * string length gets near PAGE_SIZE. Then we can savely display
* the next IPv6 address (worst case, compared to IPv4) */ * the next IPv6 address (worst case, compared to IPv4) */
if ((PAGE_SIZE - i) <= entry_len) if ((PAGE_SIZE - str_len) <= entry_len)
break; break;
qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u, qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
addr_str); addr_str);
i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str); str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "%s\n",
addr_str);
} }
spin_unlock_bh(&card->ip_lock); spin_unlock_bh(&card->ip_lock);
i += snprintf(buf + i, PAGE_SIZE - i, "\n"); str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "\n");
return i; return str_len;
} }
static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev, static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment