Skip to contentSkip to conversation

Patch "ipv6: dad: don't remove dynamic addresses if link is down" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Jul 18, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

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.4-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.4 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 ec8add2a4c9df723c94a863b8fcd6d93c472deed Mon 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 1800

The 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.

Fixes 3c21edbd1137 ("[IPV6]: Defer IPv6 device initialization until the link becomes ready.")
---
 net/ipv6/addrconf.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
net/ipv6/addrconf.c +11 -11
@@ -1772,17 +1772,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
 
 static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
 {
-	if (ifp->flags&IFA_F_PERMANENT) {
-		spin_lock_bh(&ifp->lock);
-		addrconf_del_dad_work(ifp);
-		ifp->flags |= IFA_F_TENTATIVE;
-		if (dad_failed)
-			ifp->flags |= IFA_F_DADFAILED;
-		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;
@@ -1795,6 +1785,16 @@ static void addrconf_dad_stop(struct ine
 			spin_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;
+		if (dad_failed)
+			ifp->flags |= IFA_F_DADFAILED;
+		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.4/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch