summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2015-09-13 02:09:06 +0000
committerhrs <hrs@FreeBSD.org>2015-09-13 02:09:06 +0000
commitbc4a1ace904281f5732175770fe2858d1f9a26da (patch)
tree5bd40edaa12ae31b5148270fdedf05beff0ae5d7
parent8de92fe7791878815b9af01d60cb7264e217b976 (diff)
downloadFreeBSD-src-bc4a1ace904281f5732175770fe2858d1f9a26da.zip
FreeBSD-src-bc4a1ace904281f5732175770fe2858d1f9a26da.tar.gz
MFC 287094:
- Deprecate IN6_IFF_NODAD. It was used to prevent DAD on a loopback interface but in6if_do_dad() already had a check for IFF_LOOPBACK. - Remove in6if_do_dad() check in in6_broadcast_ifa(). An address which needs DAD always has IN6_IFF_TENTATIVE there. - in6if_do_dad() now returns EAGAIN when the interface is not ready since DAD callout handler ignores such an interface. - In DAD callout handler, mark an address as IN6_IFF_TENTATIVE when the interface has ND6_IFF_IFDISABLED. And Do IFF_UP and IFF_DRV_RUNNING check consistently when DAD is required. - draft-ietf-6man-enhanced-dad is now published as RFC 7527. - Fix some typos.
-rw-r--r--sys/netinet6/in6.c21
-rw-r--r--sys/netinet6/in6_ifattach.c3
-rw-r--r--sys/netinet6/in6_var.h2
-rw-r--r--sys/netinet6/nd6_nbr.c11
4 files changed, 19 insertions, 18 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 2898d61..231b269 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1280,13 +1280,8 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
goto cleanup;
}
- /*
- * Perform DAD, if needed.
- * XXX It may be of use, if we can administratively disable DAD.
- */
- if (in6if_do_dad(ifp) && ((ifra->ifra_flags & IN6_IFF_NODAD) == 0) &&
- (ia->ia6_flags & IN6_IFF_TENTATIVE))
- {
+ /* Perform DAD, if the address is TENTATIVE. */
+ if ((ia->ia6_flags & IN6_IFF_TENTATIVE)) {
int mindelay, maxdelay;
delay = 0;
@@ -1619,6 +1614,10 @@ in6_purgeif(struct ifnet *ifp)
* in the future.
* RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
* address encoding scheme. (see figure on page 8)
+ * Notifies other subsystems about address change/arrival:
+ * 1) Notifies device handler on the first IPv6 address assignment
+ * 2) Handle routing table changes for P2P links and route
+ * 3) Handle routing table changes for address host route
*/
static int
in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
@@ -2389,13 +2388,13 @@ in6if_do_dad(struct ifnet *ifp)
* However, some interfaces can be up before the RUNNING
* status. Additionaly, users may try to assign addresses
* before the interface becomes up (or running).
- * We simply skip DAD in such a case as a work around.
- * XXX: we should rather mark "tentative" on such addresses,
- * and do DAD after the interface becomes ready.
+ * This function returns EAGAIN in that case.
+ * The caller should mark "tentative" on the address instead of
+ * performing DAD immediately.
*/
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
- return (0);
+ return (EAGAIN);
return (1);
}
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 0d42088..2381dd3 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -595,9 +595,6 @@ in6_ifattach_loopback(struct ifnet *ifp)
ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
- /* we don't need to perform DAD on loopback interfaces. */
- ifra.ifra_flags |= IN6_IFF_NODAD;
-
/*
* We are sure that this is a newly assigned address, so we can set
* NULL to the 3rd arg.
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
index fefb1ef..30dd1e8 100644
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -494,7 +494,7 @@ struct in6_rrenumreq {
#define IN6_IFF_DETACHED 0x08 /* may be detached from the link */
#define IN6_IFF_DEPRECATED 0x10 /* deprecated address */
#define IN6_IFF_NODAD 0x20 /* don't perform DAD on this address
- * (used only at first SIOC* call)
+ * (obsolete)
*/
#define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */
#define IN6_IFF_TEMPORARY 0x80 /* temporary (anonymous) address. */
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 2272cd0..8f287dc 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -576,7 +576,7 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6,
/*
* Add a Nonce option (RFC 3971) to detect looped back NS messages.
* This behavior is documented as Enhanced Duplicate Address
- * Detection in draft-ietf-6man-enhanced-dad-13.
+ * Detection in RFC 7527.
* net.inet6.ip6.dad_enhanced=0 disables this.
*/
if (V_dad_enhanced != 0 && nonce != NULL) {
@@ -1308,11 +1308,16 @@ nd6_dad_start(struct ifaddr *ifa, int delay)
}
if (ifa->ifa_ifp == NULL)
panic("nd6_dad_start: ifa->ifa_ifp == NULL");
- if (!(ifa->ifa_ifp->if_flags & IFF_UP)) {
+ if (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_NO_DAD) {
+ ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
return;
}
- if (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IFDISABLED)
+ if (!(ifa->ifa_ifp->if_flags & IFF_UP) ||
+ !(ifa->ifa_ifp->if_drv_flags & IFF_DRV_RUNNING) ||
+ (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IFDISABLED)) {
+ ia->ia6_flags |= IN6_IFF_TENTATIVE;
return;
+ }
if ((dp = nd6_dad_find(ifa, NULL)) != NULL) {
/* DAD already in progress */
nd6_dad_rele(dp);
OpenPOWER on IntegriCloud