diff options
author | hrs <hrs@FreeBSD.org> | 2015-09-13 02:09:06 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2015-09-13 02:09:06 +0000 |
commit | bc4a1ace904281f5732175770fe2858d1f9a26da (patch) | |
tree | 5bd40edaa12ae31b5148270fdedf05beff0ae5d7 | |
parent | 8de92fe7791878815b9af01d60cb7264e217b976 (diff) | |
download | FreeBSD-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.c | 21 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 3 | ||||
-rw-r--r-- | sys/netinet6/in6_var.h | 2 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 11 |
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); |