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>
This commit is contained in:
parent
cef8c79315
commit
2d921c321c
|
@ -195,7 +195,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
|
|||
{IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
|
||||
{IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
|
||||
{IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
|
||||
{IPA_RC_MULTICAST_FULL, "No task available, multicast full"},
|
||||
{IPA_RC_MC_ADDR_NOT_FOUND, "Multicast address not found"},
|
||||
{IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
|
||||
{IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
|
||||
{IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
|
||||
|
|
|
@ -182,7 +182,7 @@ enum qeth_ipa_return_codes {
|
|||
IPA_RC_SETIP_NO_STARTLAN = 0xe008,
|
||||
IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009,
|
||||
IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a,
|
||||
IPA_RC_MULTICAST_FULL = 0xe00b,
|
||||
IPA_RC_MC_ADDR_NOT_FOUND = 0xe00b,
|
||||
IPA_RC_SETIP_INVALID_VERSION = 0xe00d,
|
||||
IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e,
|
||||
IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f,
|
||||
|
|
|
@ -401,8 +401,11 @@ static int __qeth_l3_ref_ip_on_card(struct qeth_card *card,
|
|||
static void __qeth_l3_delete_all_mc(struct qeth_card *card,
|
||||
unsigned long *flags)
|
||||
{
|
||||
struct list_head fail_list;
|
||||
struct qeth_ipaddr *addr, *tmp;
|
||||
int rc;
|
||||
|
||||
INIT_LIST_HEAD(&fail_list);
|
||||
again:
|
||||
list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
|
||||
if (addr->is_multicast) {
|
||||
|
@ -410,13 +413,14 @@ again:
|
|||
spin_unlock_irqrestore(&card->ip_lock, *flags);
|
||||
rc = qeth_l3_deregister_addr_entry(card, addr);
|
||||
spin_lock_irqsave(&card->ip_lock, *flags);
|
||||
if (!rc) {
|
||||
if (!rc || (rc == IPA_RC_MC_ADDR_NOT_FOUND))
|
||||
kfree(addr);
|
||||
else
|
||||
list_add_tail(&addr->entry, &fail_list);
|
||||
goto again;
|
||||
} else
|
||||
list_add(&addr->entry, &card->ip_list);
|
||||
}
|
||||
}
|
||||
list_splice(&fail_list, &card->ip_list);
|
||||
}
|
||||
|
||||
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)
|
|||
spin_unlock_irqrestore(&card->ip_lock, flags);
|
||||
rc = qeth_l3_deregister_addr_entry(card, addr);
|
||||
spin_lock_irqsave(&card->ip_lock, flags);
|
||||
if (!rc)
|
||||
if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED))
|
||||
kfree(addr);
|
||||
else
|
||||
list_add_tail(&addr->entry, &card->ip_list);
|
||||
|
|
Loading…
Reference in New Issue