Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144050979
D54749.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D54749.diff
View Options
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -134,6 +134,8 @@
* currently used for temporary addresses only.
*/
time_t ia6_updatetime;
+ time_t ia6_dad_lastattempt; /* Last DAD attempt */
+ uint32_t ia6_dad_restarts; /* Number of restarts */
/* back pointer to the ND prefix (for autoconfigured addresses only) */
struct nd_prefix *ia6_ndpr;
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -392,6 +392,7 @@
caddr_t nd6_ifptomac(struct ifnet *);
void nd6_dad_init(void);
void nd6_dad_start(struct ifaddr *, int);
+void nd6_dad_restart(struct in6_ifaddr *);
void nd6_dad_stop(struct ifaddr *);
/* nd6_rtr.c */
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1030,9 +1030,17 @@
((ifp->if_flags & IFF_UP) == 0 ||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) != 0)){
+ nd6_dad_stop(&ia6->ia_ifa);
ia6->ia6_flags &= ~IN6_IFF_DUPLICATED;
ia6->ia6_flags |= IN6_IFF_TENTATIVE;
}
+ if ((ia6->ia6_flags & IN6_IFF_DUPLICATED) != 0) {
+ /*
+ * Retry DAD to recover in the case the other
+ * client is no longer using this address
+ */
+ nd6_dad_restart(ia6);
+ }
/*
* A new RA might have made a deprecated address
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -113,6 +113,15 @@
transmit DAD packet */
#define V_dad_maxtry VNET(dad_maxtry)
+#define MAX_DAD_RESTARTS 10 /* Maximum restarts */
+#define DAD_RESTART_INTERVAL 30 /* In seconds */
+
+VNET_DEFINE_STATIC(int, max_dad_restarts) = MAX_DAD_RESTARTS;
+#define V_max_dad_restarts VNET(max_dad_restarts)
+
+SYSCTL_INT(_net_inet6_ip6, OID_AUTO, dad_restart, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(max_dad_restarts), 0, "Maximum DAD restart attempts per address");
+
VNET_DEFINE_STATIC(int, nd6_onlink_ns_rfc4861) = 0;
#define V_nd6_onlink_ns_rfc4861 VNET(nd6_onlink_ns_rfc4861)
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_ONLINKNSRFC4861,
@@ -1337,6 +1346,33 @@
DADQ_WUNLOCK();
}
+/*
+ * Restarts the Duplicate Address Detection (DAD) process for an IPv6 interface address.
+ *
+ * This function reinitializes the DAD process for the specified IPv6 interface
+ * address (`ia6`). It is typically invoked when a DAD failure occurs or when
+ * the DAD process needs to be retried due to changes in the network state or
+ * configuration.
+ */
+void
+nd6_dad_restart(struct in6_ifaddr *ia6)
+{
+ if (((ia6->ia6_flags & IN6_IFF_DUPLICATED) == 0) ||
+ (ia6->ia6_dad_lastattempt == 0) ||
+ (ia6->ia6_dad_restarts >= V_max_dad_restarts)) {
+ return;
+ }
+
+ if (((time_uptime - ia6->ia6_dad_lastattempt) >= DAD_RESTART_INTERVAL) &&
+ ((ia6->ia6_flags & IN6_IFF_DETACHED) == 0)) {
+ ia6->ia6_dad_lastattempt = 0;
+ ia6->ia6_dad_restarts++;
+ ia6->ia6_flags &= ~IN6_IFF_DUPLICATED;
+ ia6->ia6_flags |= IN6_IFF_TENTATIVE;
+ nd6_dad_start(&ia6->ia_ifa, arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz));
+ }
+}
+
/*
* terminate DAD unconditionally. used for address removals.
*/
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 4, 10:58 PM (11 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28438267
Default Alt Text
D54749.diff (3 KB)
Attached To
Mode
D54749: netinet6: Periodically retry DAD for IPv6 addresses marked as duplicated
Attached
Detach File
Event Timeline
Log In to Comment