aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net
diff options
context:
space:
mode:
authorUrsula Braun <braunu@de.ibm.com>2008-04-01 04:26:53 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-16 20:41:38 -0400
commit2d921c321ca670201abe9eff5e53585c39e68f5e (patch)
treeac4013ca98a1f39daf53bb687d3d62232a354e93 /drivers/s390/net
parentcef8c793156402c1894776f09d75984f7748cdff (diff)
qeth: improve ip_list administration after deregister failures
1. ip_list handling after deregister failure of multicast address: If error code "MC Address not found" is returned do not re-add multicast address to ip_list. For other error codes readd multicast address at the end of function qeth_delete_all_mc. 2. ip_list handling after deregister failure or normal ip address: If error code "IP Address not found" is returned do not re-add multicast address to ip list. This is especially important in IP address takeover scenarios, to enable re-takeover of a taken over IP address. Signed-off-by: Ursula Braun <braunu@de.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/s390/net')
-rw-r--r--drivers/s390/net/qeth_core_mpc.c2
-rw-r--r--drivers/s390/net/qeth_core_mpc.h2
-rw-r--r--drivers/s390/net/qeth_l3_main.c14
3 files changed, 11 insertions, 7 deletions
diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c
index 8653b73e5dcf..441533f2062e 100644
--- a/drivers/s390/net/qeth_core_mpc.c
+++ b/drivers/s390/net/qeth_core_mpc.c
@@ -195,7 +195,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
195 {IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"}, 195 {IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
196 {IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"}, 196 {IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
197 {IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"}, 197 {IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
198 {IPA_RC_MULTICAST_FULL, "No task available, multicast full"}, 198 {IPA_RC_MC_ADDR_NOT_FOUND, "Multicast address not found"},
199 {IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"}, 199 {IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
200 {IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"}, 200 {IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
201 {IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"}, 201 {IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index de221932f30f..18548822e37c 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -182,7 +182,7 @@ enum qeth_ipa_return_codes {
182 IPA_RC_SETIP_NO_STARTLAN = 0xe008, 182 IPA_RC_SETIP_NO_STARTLAN = 0xe008,
183 IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009, 183 IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009,
184 IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a, 184 IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a,
185 IPA_RC_MULTICAST_FULL = 0xe00b, 185 IPA_RC_MC_ADDR_NOT_FOUND = 0xe00b,
186 IPA_RC_SETIP_INVALID_VERSION = 0xe00d, 186 IPA_RC_SETIP_INVALID_VERSION = 0xe00d,
187 IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e, 187 IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e,
188 IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f, 188 IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 21c439046b3c..1013a2a8ec00 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -401,8 +401,11 @@ static int __qeth_l3_ref_ip_on_card(struct qeth_card *card,
401static void __qeth_l3_delete_all_mc(struct qeth_card *card, 401static void __qeth_l3_delete_all_mc(struct qeth_card *card,
402 unsigned long *flags) 402 unsigned long *flags)
403{ 403{
404 struct list_head fail_list;
404 struct qeth_ipaddr *addr, *tmp; 405 struct qeth_ipaddr *addr, *tmp;
405 int rc; 406 int rc;
407
408 INIT_LIST_HEAD(&fail_list);
406again: 409again:
407 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) { 410 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
408 if (addr->is_multicast) { 411 if (addr->is_multicast) {
@@ -410,13 +413,14 @@ again:
410 spin_unlock_irqrestore(&card->ip_lock, *flags); 413 spin_unlock_irqrestore(&card->ip_lock, *flags);
411 rc = qeth_l3_deregister_addr_entry(card, addr); 414 rc = qeth_l3_deregister_addr_entry(card, addr);
412 spin_lock_irqsave(&card->ip_lock, *flags); 415 spin_lock_irqsave(&card->ip_lock, *flags);
413 if (!rc) { 416 if (!rc || (rc == IPA_RC_MC_ADDR_NOT_FOUND))
414 kfree(addr); 417 kfree(addr);
415 goto again; 418 else
416 } else 419 list_add_tail(&addr->entry, &fail_list);
417 list_add(&addr->entry, &card->ip_list); 420 goto again;
418 } 421 }
419 } 422 }
423 list_splice(&fail_list, &card->ip_list);
420} 424}
421 425
422static void qeth_l3_set_ip_addr_list(struct qeth_card *card) 426static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
@@ -467,7 +471,7 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
467 spin_unlock_irqrestore(&card->ip_lock, flags); 471 spin_unlock_irqrestore(&card->ip_lock, flags);
468 rc = qeth_l3_deregister_addr_entry(card, addr); 472 rc = qeth_l3_deregister_addr_entry(card, addr);
469 spin_lock_irqsave(&card->ip_lock, flags); 473 spin_lock_irqsave(&card->ip_lock, flags);
470 if (!rc) 474 if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED))
471 kfree(addr); 475 kfree(addr);
472 else 476 else
473 list_add_tail(&addr->entry, &card->ip_list); 477 list_add_tail(&addr->entry, &card->ip_list);