diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 4c387dc338e3..c1e124bc8e1e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -242,6 +242,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { #ifdef CONFIG_IPV6_SEG6_HMAC .seg6_require_hmac = 0, #endif + .enhanced_dad = 1, }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -292,6 +293,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { #ifdef CONFIG_IPV6_SEG6_HMAC .seg6_require_hmac = 0, #endif + .enhanced_dad = 1, }; /* Check if a valid qdisc is available */ @@ -3735,12 +3737,21 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) { unsigned long rand_num; struct inet6_dev *idev = ifp->idev; + u64 nonce; if (ifp->flags & IFA_F_OPTIMISTIC) rand_num = 0; else rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); + nonce = 0; + if (idev->cnf.enhanced_dad || + dev_net(idev->dev)->ipv6.devconf_all->enhanced_dad) { + do + get_random_bytes(&nonce, 6); + while (nonce == 0); + } + ifp->dad_nonce = nonce; ifp->dad_probes = idev->cnf.dad_transmits; addrconf_mod_dad_work(ifp, rand_num); } @@ -3918,7 +3929,8 @@ static void addrconf_dad_work(struct work_struct *w) /* send a neighbour solicitation for our addr */ addrconf_addr_solict_mult(&ifp->addr, &mcaddr); - ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any); + ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any, + ifp->dad_nonce); out: in6_ifa_put(ifp); rtnl_unlock(); @@ -4962,6 +4974,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, #ifdef CONFIG_IPV6_SEG6_HMAC array[DEVCONF_SEG6_REQUIRE_HMAC] = cnf->seg6_require_hmac; #endif + array[DEVCONF_ENHANCED_DAD] = cnf->enhanced_dad; } static inline size_t inet6_ifla6_size(void) @@ -6070,6 +6083,13 @@ static const struct ctl_table addrconf_sysctl[] = { }, #endif { + .procname = "enhanced_dad", + .data = &ipv6_devconf.enhanced_dad, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { /* sentinel */ } }; |