|
@@ -590,6 +590,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
|
|
|
{
|
|
|
struct inet6_ifaddr *ifa = NULL;
|
|
|
struct rt6_info *rt;
|
|
|
+ struct net *net = dev_net(idev->dev);
|
|
|
int hash;
|
|
|
int err = 0;
|
|
|
int addr_type = ipv6_addr_type(addr);
|
|
@@ -606,6 +607,11 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
|
|
|
goto out2;
|
|
|
}
|
|
|
|
|
|
+ if (idev->cnf.disable_ipv6 || net->ipv6.devconf_all->disable_ipv6) {
|
|
|
+ err = -EACCES;
|
|
|
+ goto out2;
|
|
|
+ }
|
|
|
+
|
|
|
write_lock(&addrconf_hash_lock);
|
|
|
|
|
|
/* Ignore adding duplicate addresses on an interface */
|
|
@@ -1433,6 +1439,11 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
|
|
|
void addrconf_dad_failure(struct inet6_ifaddr *ifp)
|
|
|
{
|
|
|
struct inet6_dev *idev = ifp->idev;
|
|
|
+
|
|
|
+ if (net_ratelimit())
|
|
|
+ printk(KERN_INFO "%s: IPv6 duplicate address detected!\n",
|
|
|
+ ifp->idev->dev->name);
|
|
|
+
|
|
|
if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
|
|
|
struct in6_addr addr;
|
|
|
|
|
@@ -1443,11 +1454,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
|
|
|
ipv6_addr_equal(&ifp->addr, &addr)) {
|
|
|
/* DAD failed for link-local based on MAC address */
|
|
|
idev->cnf.disable_ipv6 = 1;
|
|
|
+
|
|
|
+ printk(KERN_INFO "%s: IPv6 being disabled!\n",
|
|
|
+ ifp->idev->dev->name);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (net_ratelimit())
|
|
|
- printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
|
|
|
addrconf_dad_stop(ifp);
|
|
|
}
|
|
|
|
|
@@ -2823,11 +2835,6 @@ static void addrconf_dad_timer(unsigned long data)
|
|
|
read_unlock_bh(&idev->lock);
|
|
|
goto out;
|
|
|
}
|
|
|
- if (idev->cnf.accept_dad > 1 && idev->cnf.disable_ipv6) {
|
|
|
- read_unlock_bh(&idev->lock);
|
|
|
- addrconf_dad_failure(ifp);
|
|
|
- return;
|
|
|
- }
|
|
|
spin_lock_bh(&ifp->lock);
|
|
|
if (ifp->probes == 0) {
|
|
|
/*
|