Patch "ipv6: dad: don't remove dynamic addresses if link is down" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
ipv6: dad: don't remove dynamic addresses if link is down
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
ec8add2a4c9df723c94a863b8fcd6d93c472deedMon Sep 17 00:00:00 2001
From: Sabrina Dubroca <[email protected]>
Date: Thu, 29 Jun 2017 16:56:54 +0200
Subject: ipv6: dad: don't remove dynamic addresses if link is down
From: Sabrina Dubroca <[email protected]>
commit ec8add2a4c9df723c94a863b8fcd6d93c472deed upstream.
Currently, when the link for $DEV is down, this command succeeds but the address is removed immediately by DAD (1):
ip addr add 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
In the same situation, this will succeed and not remove the address (2):
ip addr add 1111::12/64 dev $DEV
ip addr change 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800The comment in addrconf_dad_begin() when !IF_READY makes it look like this is the intended behavior, but doesn't explain why:
* If the device is not ready:
* - keep it tentative if it is a permanent address.
* - otherwise, kill it.
We clearly cannot prevent userspace from doing (2), but we can make (1) work consistently with (2).
addrconf_dad_stop() is only called in two cases: if DAD failed, or to skip DAD when the link is down. In that second case, the fix is to avoid deleting the address, like we already do for permanent addresses.
--- net/ipv6/addrconf.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
net/ipv6/addrconf.c +9 -9
@@ -1875,15 +1875,7 @@ static void addrconf_dad_stop(struct ineif (dad_failed) ifp->flags |=IFA_F_DADFAILED ; -if (ifp->flags&IFA_F_PERMANENT ) { -spin_lock_bh (&ifp->lock); -addrconf_del_dad_work (ifp); - ifp->flags |=IFA_F_TENTATIVE ; -spin_unlock_bh (&ifp->lock); -if (dad_failed) -ipv6_ifa_notify (0 , ifp); -in6_ifa_put (ifp); - }else if (ifp->flags&IFA_F_TEMPORARY ) { +if (ifp->flags&IFA_F_TEMPORARY ) {struct inet6_ifaddr *ifpub;spin_lock_bh (&ifp->lock); ifpub = ifp->ifpub;
@@ -1896,6 +1888,14 @@ static void addrconf_dad_stop(struct inespin_unlock_bh (&ifp->lock); }ipv6_del_addr (ifp); + }else if (ifp->flags&IFA_F_PERMANENT || !dad_failed) { +spin_lock_bh (&ifp->lock); +addrconf_del_dad_work (ifp); + ifp->flags |=IFA_F_TENTATIVE ; +spin_unlock_bh (&ifp->lock); +if (dad_failed) +ipv6_ifa_notify (0 , ifp); +in6_ifa_put (ifp); }else {ipv6_del_addr (ifp); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch