diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e83852ab4dc8..717584bad02e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -590,6 +590,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
590 | { | 590 | { |
591 | struct inet6_ifaddr *ifa = NULL; | 591 | struct inet6_ifaddr *ifa = NULL; |
592 | struct rt6_info *rt; | 592 | struct rt6_info *rt; |
593 | struct net *net = dev_net(idev->dev); | ||
593 | int hash; | 594 | int hash; |
594 | int err = 0; | 595 | int err = 0; |
595 | int addr_type = ipv6_addr_type(addr); | 596 | 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, | |||
606 | goto out2; | 607 | goto out2; |
607 | } | 608 | } |
608 | 609 | ||
610 | if (idev->cnf.disable_ipv6 || net->ipv6.devconf_all->disable_ipv6) { | ||
611 | err = -EACCES; | ||
612 | goto out2; | ||
613 | } | ||
614 | |||
609 | write_lock(&addrconf_hash_lock); | 615 | write_lock(&addrconf_hash_lock); |
610 | 616 | ||
611 | /* Ignore adding duplicate addresses on an interface */ | 617 | /* Ignore adding duplicate addresses on an interface */ |
@@ -1433,6 +1439,11 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp) | |||
1433 | void addrconf_dad_failure(struct inet6_ifaddr *ifp) | 1439 | void addrconf_dad_failure(struct inet6_ifaddr *ifp) |
1434 | { | 1440 | { |
1435 | struct inet6_dev *idev = ifp->idev; | 1441 | struct inet6_dev *idev = ifp->idev; |
1442 | |||
1443 | if (net_ratelimit()) | ||
1444 | printk(KERN_INFO "%s: IPv6 duplicate address detected!\n", | ||
1445 | ifp->idev->dev->name); | ||
1446 | |||
1436 | if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) { | 1447 | if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) { |
1437 | struct in6_addr addr; | 1448 | struct in6_addr addr; |
1438 | 1449 | ||
@@ -1443,11 +1454,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
1443 | ipv6_addr_equal(&ifp->addr, &addr)) { | 1454 | ipv6_addr_equal(&ifp->addr, &addr)) { |
1444 | /* DAD failed for link-local based on MAC address */ | 1455 | /* DAD failed for link-local based on MAC address */ |
1445 | idev->cnf.disable_ipv6 = 1; | 1456 | idev->cnf.disable_ipv6 = 1; |
1457 | |||
1458 | printk(KERN_INFO "%s: IPv6 being disabled!\n", | ||
1459 | ifp->idev->dev->name); | ||
1446 | } | 1460 | } |
1447 | } | 1461 | } |
1448 | 1462 | ||
1449 | if (net_ratelimit()) | ||
1450 | printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name); | ||
1451 | addrconf_dad_stop(ifp); | 1463 | addrconf_dad_stop(ifp); |
1452 | } | 1464 | } |
1453 | 1465 | ||
@@ -2823,11 +2835,6 @@ static void addrconf_dad_timer(unsigned long data) | |||
2823 | read_unlock_bh(&idev->lock); | 2835 | read_unlock_bh(&idev->lock); |
2824 | goto out; | 2836 | goto out; |
2825 | } | 2837 | } |
2826 | if (idev->cnf.accept_dad > 1 && idev->cnf.disable_ipv6) { | ||
2827 | read_unlock_bh(&idev->lock); | ||
2828 | addrconf_dad_failure(ifp); | ||
2829 | return; | ||
2830 | } | ||
2831 | spin_lock_bh(&ifp->lock); | 2838 | spin_lock_bh(&ifp->lock); |
2832 | if (ifp->probes == 0) { | 2839 | if (ifp->probes == 0) { |
2833 | /* | 2840 | /* |