All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simone Piunno <pioppo@ferrara.linux.it>
To: netdev@oss.sgi.com, usagi-users@linux-ipv6.org
Cc: linux-kernel@vger.kernel.org, ds6-devel@deepspace6.net
Subject: IPv6 duplicate address bugfix
Date: Sun, 30 Mar 2003 14:27:05 +0200	[thread overview]
Message-ID: <20030330122705.GA18283@ferrara.linux.it> (raw)


Hi,

When adding an IPv6 address to a given interface, I'm allowed to
add that address multiple time, e.g.:

[root@abulafia root]# ip addr add 3ffe:4242:4242::1 dev eth0
[root@abulafia root]# ip addr add 3ffe:4242:4242::1 dev eth0
[root@abulafia root]# ip addr add 3ffe:4242:4242::1 dev eth0
[root@abulafia root]# ip addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
    inet6 3ffe:4242:4242::1/128 scope global 
    inet6 3ffe:4242:4242::1/128 scope global 
    inet6 3ffe:4242:4242::1/128 scope global 
    inet6 fe80::248:54ff:fe1b:2530/10 scope link

Apparently, this is not a stability problem, because I'm allowed to 
delete 3 times that address before receving a "not found" error,
but there's no reason to allow multiple instances of the same address 
on the same interface, so this is a bug nonetheless.

Bug is confirmed on:
  - 2.4.20
  - 2.5.66
  - latest -usagi

Following is a patch attempting to fix this bug.
It's for 2.4.20 but sould apply cleanly on 2.5 too.

Credits:
  Chad N. Tindel  - discovered the bug and showed it to me
  Peter Bieringer - confirmed it's a bug
  Mauro Tortonesi - suggested sending a patch to this list.

Regards,
  Simone Piunno


--- net/ipv6/addrconf.c.orig	2003-03-25 21:33:55.000000000 +0100
+++ net/ipv6/addrconf.c	2003-03-30 13:48:23.000000000 +0200
@@ -89,6 +89,8 @@
 static struct inet6_ifaddr		*inet6_addr_lst[IN6_ADDR_HSIZE];
 static rwlock_t	addrconf_hash_lock = RW_LOCK_UNLOCKED;
 
+static spinlock_t addrconf_add_lock = SPIN_LOCK_UNLOCKED;
+
 /* Protects inet6 devices */
 rwlock_t addrconf_lock = RW_LOCK_UNLOCKED;
 
@@ -621,6 +623,24 @@
 	return ifp != NULL;
 }
 
+static struct inet6_ifaddr *
+ipv6_addr_already_present(struct in6_addr *addr, struct net_device *dev)
+{
+	struct inet6_ifaddr *ifp;
+	u8 hash = ipv6_addr_hash(addr);
+	
+	read_lock_bh(&addrconf_hash_lock);
+	for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
+		if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && ifp->idev->dev == dev) {
+			read_unlock_bh(&addrconf_hash_lock);
+			return ifp;
+		}
+	}
+	read_unlock_bh(&addrconf_hash_lock);
+	return NULL;
+}
+
+
 struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev)
 {
 	struct inet6_ifaddr * ifp;
@@ -908,7 +928,7 @@
 		return;
 
 ok:
-
+		spin_lock_bh(&addrconf_add_lock);
 		ifp = ipv6_get_ifaddr(&addr, dev);
 
 		if (ifp == NULL && valid_lft) {
@@ -920,12 +940,14 @@
 						    addr_type&IPV6_ADDR_SCOPE_MASK, 0);
 
 			if (ifp == NULL) {
+				spin_unlock_bh(&addrconf_add_lock);
 				in6_dev_put(in6_dev);
 				return;
 			}
 
 			addrconf_dad_start(ifp);
 		}
+		spin_unlock_bh(&addrconf_add_lock);
 
 		if (ifp && valid_lft == 0) {
 			ipv6_del_addr(ifp);
@@ -1033,11 +1055,19 @@
 
 	scope = ipv6_addr_scope(pfx);
 
+	spin_lock_bh(&addrconf_add_lock);
+	if (ipv6_addr_already_present(pfx, dev)) {
+		spin_unlock_bh(&addrconf_add_lock);
+		return -EEXIST;
+	}
+
 	if ((ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT)) != NULL) {
+		spin_unlock_bh(&addrconf_add_lock);
 		addrconf_dad_start(ifp);
 		in6_ifa_put(ifp);
 		return 0;
 	}
+	spin_unlock_bh(&addrconf_add_lock);
 
 	return -ENOBUFS;
 }
-- 
 Simone Piunno -- http://members.ferrara.linux.it/pioppo 
.-------  Adde parvum parvo magnus acervus erit  -------.
 Ferrara Linux Users Group - http://www.ferrara.linux.it 
 Deep Space 6, IPv6 on Linux - http://www.deepspace6.net 
 GNU Mailman, Mailing List Manager - http://www.list.org 
`-------------------------------------------------------'

             reply	other threads:[~2003-03-30 12:25 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-30 12:27 Simone Piunno [this message]
2003-03-30 13:08 ` (usagi-users 02296) IPv6 duplicate address bugfix YOSHIFUJI Hideaki / 吉藤英明
2003-03-30 14:58   ` [PATCH] IPv6: Don't assign a same IPv6 address on a same interface (is Re: IPv6 duplicate address bugfix) YOSHIFUJI Hideaki / 吉藤英明
2003-03-30 16:36     ` Simone Piunno
2003-03-30 18:35       ` YOSHIFUJI Hideaki / 吉藤英明
2003-03-31  1:34         ` [PATCH] IPv6: Don't assign a same IPv6 address on a same interface YOSHIFUJI Hideaki / 吉藤英明
2003-03-31 19:05           ` David S. Miller
2003-03-31 18:23 ` (usagi-users 02296) IPv6 duplicate address bugfix Peter Bieringer
2003-03-31 18:56   ` [ds6-devel] " Simone Piunno

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=20030330122705.GA18283@ferrara.linux.it \
    --to=pioppo@ferrara.linux.it \
    --cc=ds6-devel@deepspace6.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@oss.sgi.com \
    --cc=usagi-users@linux-ipv6.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.