netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Heiner Kallweit <heiner.kallweit@web.de>
To: "netdev@vger.kernel.org" <netdev@vger.kernel.org>
Subject: [PATCH net] ipv6: If a public address is deleted then also delete all temporary addresses still referring to it
Date: Tue, 18 Mar 2014 21:46:40 +0100	[thread overview]
Message-ID: <5328B0B0.7070305@web.de> (raw)

If a public address is deleted by an external trigger (e.g. via inet6_rtm_deladdr) then temporary
addresses still referring to it may remain. Happened here when the WiFi link broke and netifd
deleted the public address. Once the link was back and prefix_rcv created new public addresses
ipv6_create_tempaddr complained that the temporary address already existed.
IMHO no temporary address should live longer than its parent, especially because ifpub of the
temporary address still points to the then deleted public address otherwise.

Therefore delete all related temporary addresses before a public address is deleted in inet6_addr_del
which is called by inet6_rtm_del.

Also ensure in ipv6_del_addr that no temporary address lives longer than its parent.
However in addrconf_verify it might not be predetermined in which order a public address and the related
temporary address are deleted if they expire at the same time. Not sure about that ..

Signed-off-by: Heiner Kallweit <heiner.kallweit@web.de>
---
 net/ipv6/addrconf.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 344e972..e5fd81d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -126,6 +126,7 @@ static void ipv6_regen_rndid(unsigned long data);
 
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
 static int ipv6_count_addresses(struct inet6_dev *idev);
+static void ipv6_del_addr(struct inet6_ifaddr *ifp);
 
 /*
  *	Configured unicast address hash table
@@ -308,6 +309,31 @@ err_ip:
 	return -ENOMEM;
 }
 
+/* delete all temporary addresses referring to ifp
+   returns true if there have been addresses to be deleted */
+static int ifa_del_tempaddrs(struct inet6_ifaddr *ifp)
+{
+        struct inet6_dev *idev = ifp->idev;
+        struct inet6_ifaddr *ift;
+        int deleted = 0;
+
+        if(!(ifp->flags & IFA_F_MANAGETEMPADDR))
+                return 0;
+restart:
+        read_lock_bh(&idev->lock);
+        list_for_each_entry(ift, &idev->tempaddr_list, tmp_list) {
+                if (ifp != ift->ifpub)
+                        continue;
+                in6_ifa_hold(ift);
+                read_unlock_bh(&idev->lock);
+                deleted = 1;
+                ipv6_del_addr(ift);
+                goto restart;
+        }
+        read_unlock_bh(&idev->lock);
+        return deleted;
+}
+
 static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 {
 	struct inet6_dev *ndev;
@@ -990,6 +1016,10 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
 	enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP;
 	unsigned long expires;
 
+	/* there should be no temporary address still referring to ifp */
+        if(ifa_del_tempaddrs(ifp))
+                pr_info("%s: stale temporary address(es) deleted\n", __func__);
+
 	spin_lock_bh(&ifp->state_lock);
 	state = ifp->state;
 	ifp->state = INET6_IFADDR_STATE_DEAD;
@@ -2506,6 +2536,7 @@ static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *p
 			in6_ifa_hold(ifp);
 			read_unlock_bh(&idev->lock);
 
+			ifa_del_tempaddrs(ifp);
 			ipv6_del_addr(ifp);
 			return 0;
 		}
-- 
1.9.0.258.g00eda23.dirty

             reply	other threads:[~2014-03-18 20:47 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-18 20:46 Heiner Kallweit [this message]
2014-03-19 20:21 ` [PATCH net] ipv6: If a public address is deleted then also delete all temporary addresses still referring to it Hannes Frederic Sowa
2014-03-19 21:17   ` Heiner Kallweit
2014-03-19 22:41     ` Hannes Frederic Sowa
2014-03-19 23:40       ` Heiner Kallweit
2014-03-26 20:27       ` Heiner Kallweit
2014-03-26 21:50         ` Heiner Kallweit
2014-03-27  2:53           ` Hannes Frederic Sowa
2014-04-06 18:56             ` Heiner Kallweit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5328B0B0.7070305@web.de \
    --to=heiner.kallweit@web.de \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).