diff options
author | Ursula Braun <braunu@de.ibm.com> | 2008-04-01 04:26:53 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-16 20:41:38 -0400 |
commit | 2d921c321ca670201abe9eff5e53585c39e68f5e (patch) | |
tree | ac4013ca98a1f39daf53bb687d3d62232a354e93 /drivers | |
parent | cef8c793156402c1894776f09d75984f7748cdff (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')
-rw-r--r-- | drivers/s390/net/qeth_core_mpc.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_mpc.h | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 14 |
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, | |||
401 | static void __qeth_l3_delete_all_mc(struct qeth_card *card, | 401 | static 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); | ||
406 | again: | 409 | again: |
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 | ||
422 | static void qeth_l3_set_ip_addr_list(struct qeth_card *card) | 426 | static 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); |