Skip to content

Commit 35e015e

Browse files
teknoraverdavem330
authored andcommitted
ipv6: fix net.ipv6.conf.all interface DAD handlers
Currently, writing into net.ipv6.conf.all.{accept_dad,use_optimistic,optimistic_dad} has no effect. Fix handling of these flags by: - using the maximum of global and per-interface values for the accept_dad flag. That is, if at least one of the two values is non-zero, enable DAD on the interface. If at least one value is set to 2, enable DAD and disable IPv6 operation on the interface if MAC-based link-local address was found - using the logical OR of global and per-interface values for the optimistic_dad flag. If at least one of them is set to one, optimistic duplicate address detection (RFC 4429) is enabled on the interface - using the logical OR of global and per-interface values for the use_optimistic flag. If at least one of them is set to one, optimistic addresses won't be marked as deprecated during source address selection on the interface. While at it, as we're modifying the prototype for ipv6_use_optimistic_addr(), drop inline, and let the compiler decide. Fixes: 7fd2561 ("net: ipv6: Add a sysctl to make optimistic addresses useful candidates") Signed-off-by: Matteo Croce <mcroce@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6819a14 commit 35e015e

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

Documentation/networking/ip-sysctl.txt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,9 @@ accept_dad - INTEGER
16801680
2: Enable DAD, and disable IPv6 operation if MAC-based duplicate
16811681
link-local address has been found.
16821682

1683+
DAD operation and mode on a given interface will be selected according
1684+
to the maximum value of conf/{all,interface}/accept_dad.
1685+
16831686
force_tllao - BOOLEAN
16841687
Enable sending the target link-layer address option even when
16851688
responding to a unicast neighbor solicitation.
@@ -1727,16 +1730,23 @@ suppress_frag_ndisc - INTEGER
17271730

17281731
optimistic_dad - BOOLEAN
17291732
Whether to perform Optimistic Duplicate Address Detection (RFC 4429).
1730-
0: disabled (default)
1731-
1: enabled
1733+
0: disabled (default)
1734+
1: enabled
1735+
1736+
Optimistic Duplicate Address Detection for the interface will be enabled
1737+
if at least one of conf/{all,interface}/optimistic_dad is set to 1,
1738+
it will be disabled otherwise.
17321739

17331740
use_optimistic - BOOLEAN
17341741
If enabled, do not classify optimistic addresses as deprecated during
17351742
source address selection. Preferred addresses will still be chosen
17361743
before optimistic addresses, subject to other ranking in the source
17371744
address selection algorithm.
1738-
0: disabled (default)
1739-
1: enabled
1745+
0: disabled (default)
1746+
1: enabled
1747+
1748+
This will be enabled if at least one of
1749+
conf/{all,interface}/use_optimistic is set to 1, disabled otherwise.
17401750

17411751
stable_secret - IPv6 address
17421752
This IPv6 address will be used as a secret to generate IPv6

net/ipv6/addrconf.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,10 +1399,18 @@ static inline int ipv6_saddr_preferred(int type)
13991399
return 0;
14001400
}
14011401

1402-
static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev)
1402+
static bool ipv6_use_optimistic_addr(struct net *net,
1403+
struct inet6_dev *idev)
14031404
{
14041405
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1405-
return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic;
1406+
if (!idev)
1407+
return false;
1408+
if (!net->ipv6.devconf_all->optimistic_dad && !idev->cnf.optimistic_dad)
1409+
return false;
1410+
if (!net->ipv6.devconf_all->use_optimistic && !idev->cnf.use_optimistic)
1411+
return false;
1412+
1413+
return true;
14061414
#else
14071415
return false;
14081416
#endif
@@ -1472,7 +1480,7 @@ static int ipv6_get_saddr_eval(struct net *net,
14721480
/* Rule 3: Avoid deprecated and optimistic addresses */
14731481
u8 avoid = IFA_F_DEPRECATED;
14741482

1475-
if (!ipv6_use_optimistic_addr(score->ifa->idev))
1483+
if (!ipv6_use_optimistic_addr(net, score->ifa->idev))
14761484
avoid |= IFA_F_OPTIMISTIC;
14771485
ret = ipv6_saddr_preferred(score->addr_type) ||
14781486
!(score->ifa->flags & avoid);
@@ -2460,7 +2468,8 @@ int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
24602468
int max_addresses = in6_dev->cnf.max_addresses;
24612469

24622470
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
2463-
if (in6_dev->cnf.optimistic_dad &&
2471+
if ((net->ipv6.devconf_all->optimistic_dad ||
2472+
in6_dev->cnf.optimistic_dad) &&
24642473
!net->ipv6.devconf_all->forwarding && sllao)
24652474
addr_flags |= IFA_F_OPTIMISTIC;
24662475
#endif
@@ -3051,7 +3060,8 @@ void addrconf_add_linklocal(struct inet6_dev *idev,
30513060
u32 addr_flags = flags | IFA_F_PERMANENT;
30523061

30533062
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
3054-
if (idev->cnf.optimistic_dad &&
3063+
if ((dev_net(idev->dev)->ipv6.devconf_all->optimistic_dad ||
3064+
idev->cnf.optimistic_dad) &&
30553065
!dev_net(idev->dev)->ipv6.devconf_all->forwarding)
30563066
addr_flags |= IFA_F_OPTIMISTIC;
30573067
#endif
@@ -3810,6 +3820,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
38103820
goto out;
38113821

38123822
if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
3823+
dev_net(dev)->ipv6.devconf_all->accept_dad < 1 ||
38133824
idev->cnf.accept_dad < 1 ||
38143825
!(ifp->flags&IFA_F_TENTATIVE) ||
38153826
ifp->flags & IFA_F_NODAD) {
@@ -3841,7 +3852,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
38413852
*/
38423853
if (ifp->flags & IFA_F_OPTIMISTIC) {
38433854
ip6_ins_rt(ifp->rt);
3844-
if (ipv6_use_optimistic_addr(idev)) {
3855+
if (ipv6_use_optimistic_addr(dev_net(dev), idev)) {
38453856
/* Because optimistic nodes can use this address,
38463857
* notify listeners. If DAD fails, RTM_DELADDR is sent.
38473858
*/
@@ -3897,7 +3908,9 @@ static void addrconf_dad_work(struct work_struct *w)
38973908
action = DAD_ABORT;
38983909
ifp->state = INET6_IFADDR_STATE_POSTDAD;
38993910

3900-
if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6 &&
3911+
if ((dev_net(idev->dev)->ipv6.devconf_all->accept_dad > 1 ||
3912+
idev->cnf.accept_dad > 1) &&
3913+
!idev->cnf.disable_ipv6 &&
39013914
!(ifp->flags & IFA_F_STABLE_PRIVACY)) {
39023915
struct in6_addr addr;
39033916

0 commit comments

Comments
 (0)