summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_spppsubr.c5
-rw-r--r--sys/netinet6/in6.c37
-rw-r--r--sys/netinet6/in6_ifattach.c37
-rw-r--r--sys/netinet6/in6_var.h5
-rw-r--r--sys/netinet6/nd6.h4
-rw-r--r--sys/netinet6/nd6_nbr.c54
-rw-r--r--sys/netinet6/nd6_rtr.c12
7 files changed, 48 insertions, 106 deletions
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index 22bf11be23b..9d937b08e0c 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_spppsubr.c,v 1.136 2015/07/18 15:51:16 mpi Exp $ */
+/* $OpenBSD: if_spppsubr.c,v 1.137 2015/08/24 15:58:35 mpi Exp $ */
/*
* Synchronous PPP/Cisco link level subroutines.
* Keepalive protocol implemented in both Cisco and PPP modes.
@@ -4790,9 +4790,6 @@ sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src,
*/
ifra->ifra_prefixmask.sin6_family = AF_UNSPEC;
- /* DAD is redundant after an IPv6CP exchange. */
- ifra->ifra_flags |= IN6_IFF_NODAD;
-
task_add(systq, &sp->ipv6cp.set_addr_task);
}
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 6773b0d998b..b3085cbf219 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.c,v 1.166 2015/08/24 14:00:29 bluhm Exp $ */
+/* $OpenBSD: in6.c,v 1.167 2015/08/24 15:58:35 mpi Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
@@ -468,11 +468,19 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
/* reject read-only flags */
if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
(ifra->ifra_flags & IN6_IFF_DETACHED) != 0 ||
- (ifra->ifra_flags & IN6_IFF_NODAD) != 0 ||
(ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0 ||
(ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0) {
return (EINVAL);
}
+
+ /*
+ * Make the address tentative before joining multicast
+ * addresses, so that corresponding MLD responses would
+ * not have a tentative source address.
+ */
+ if ((ia6 == NULL) && in6if_do_dad(ifp))
+ ifra->ifra_flags |= IN6_IFF_TENTATIVE;
+
/*
* first, make or update the interface address structure,
* and link it to the list. try to enable inet6 if there
@@ -497,6 +505,11 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
break;
}
+ /* Perform DAD, if needed. */
+ if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
+ nd6_dad_start(&ia6->ia_ifa);
+
+
plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL);
if (plen == 128) {
dohooks(ifp->if_addrhooks, 0);
@@ -753,15 +766,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
* configure address flags.
*/
ia6->ia6_flags = ifra->ifra_flags;
- /*
- * Make the address tentative before joining multicast addresses,
- * so that corresponding MLD responses would not have a tentative
- * source address.
- */
- ia6->ia6_flags &= ~IN6_IFF_DUPLICATED; /* safety */
- if (hostIsNew && in6if_do_dad(ifp) &&
- (ifra->ifra_flags & IN6_IFF_NODAD) == 0)
- ia6->ia6_flags |= IN6_IFF_TENTATIVE;
/*
* We are done if we have simply modified an existing address.
@@ -908,17 +912,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
}
- /*
- * Perform DAD, if needed.
- * XXX It may be of use, if we can administratively
- * disable DAD.
- */
- if (hostIsNew && in6if_do_dad(ifp) &&
- (ifra->ifra_flags & IN6_IFF_NODAD) == 0)
- {
- nd6_dad_start(&ia6->ia_ifa, NULL);
- }
-
return (error);
unlink:
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 4c7dc3cf6c0..6c6a65af67a 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_ifattach.c,v 1.91 2015/08/17 10:57:24 mpi Exp $ */
+/* $OpenBSD: in6_ifattach.c,v 1.92 2015/08/24 15:58:35 mpi Exp $ */
/* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */
/*
@@ -292,7 +292,6 @@ success:
int
in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
{
- struct in6_ifaddr *ia6;
struct in6_aliasreq ifra;
int s, error;
@@ -332,12 +331,6 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
/*
- * Do not let in6_update_ifa() do DAD, since we need a random delay
- * before sending an NS at the first time the interface becomes up.
- */
- ifra.ifra_flags |= IN6_IFF_NODAD;
-
- /*
* Now call in6_update_ifa() to do a bunch of procedures to configure
* a link-local address. In the case of CARP, we may be called after
* one has already been configured, so check if it's already there
@@ -363,21 +356,17 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
}
/*
- * Adjust ia6_flags so that in6_ifattach() will perform DAD.
+ * Perform DAD.
+ *
* XXX: Some P2P interfaces seem not to send packets just after
* becoming up, so we skip p2p interfaces for safety.
*/
- ia6 = in6ifa_ifpforlinklocal(ifp, 0); /* ia6 must not be NULL */
-#ifdef DIAGNOSTIC
- if (!ia6) {
- panic("ia6 == NULL in in6_ifattach_linklocal");
- /* NOTREACHED */
- }
-#endif
if (in6if_do_dad(ifp) && ((ifp->if_flags & IFF_POINTOPOINT) ||
(ifp->if_type == IFT_CARP)) == 0) {
- ia6->ia6_flags &= ~IN6_IFF_NODAD;
+ struct in6_ifaddr *ia6;
+ ia6 = in6ifa_ifpforlinklocal(ifp, 0);
ia6->ia6_flags |= IN6_IFF_TENTATIVE;
+ nd6_dad_start(&ia6->ia_ifa);
}
/*
@@ -423,9 +412,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.
@@ -492,9 +478,6 @@ in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
int
in6_ifattach(struct ifnet *ifp)
{
- struct ifaddr *ifa;
- int dad_delay = 0; /* delay ticks before DAD output */
-
/* some of the interfaces are inherently not IPv6 capable */
switch (ifp->if_type) {
case IFT_BRIDGE:
@@ -531,14 +514,6 @@ in6_ifattach(struct ifnet *ifp)
return (in6_ifattach_loopback(ifp));
}
- /* Perform DAD. */
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family != AF_INET6)
- continue;
- if (ifatoia6(ifa)->ia6_flags & IN6_IFF_TENTATIVE)
- nd6_dad_start(ifa, &dad_delay);
- }
-
if (ifp->if_xflags & IFXF_AUTOCONF6)
nd6_rs_attach(ifp);
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
index aebbcefc9cf..e4f4ae98ba0 100644
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_var.h,v 1.52 2015/07/08 08:48:34 mpi Exp $ */
+/* $OpenBSD: in6_var.h,v 1.53 2015/08/24 15:58:35 mpi Exp $ */
/* $KAME: in6_var.h,v 1.55 2001/02/16 12:49:45 itojun Exp $ */
/*
@@ -433,9 +433,6 @@ struct in6_rrenumreq {
#define IN6_IFF_DUPLICATED 0x04 /* DAD detected duplicate */
#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)
- */
#define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */
#define IN6_IFF_PRIVACY 0x80 /* RFC 4941 temporary address */
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index c6393a1d515..543d94d7cd9 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6.h,v 1.45 2015/08/18 08:52:25 mpi Exp $ */
+/* $OpenBSD: nd6.h,v 1.46 2015/08/24 15:58:35 mpi Exp $ */
/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
/*
@@ -291,7 +291,7 @@ void nd6_ns_input(struct mbuf *, int, int);
void nd6_ns_output(struct ifnet *, struct in6_addr *,
struct in6_addr *, struct llinfo_nd6 *, int);
caddr_t nd6_ifptomac(struct ifnet *);
-void nd6_dad_start(struct ifaddr *, int *);
+void nd6_dad_start(struct ifaddr *);
void nd6_dad_stop(struct ifaddr *);
void nd6_ra_input(struct mbuf *, int, int);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index c393173e836..0eae5db1250 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_nbr.c,v 1.91 2015/07/16 15:28:38 mpi Exp $ */
+/* $OpenBSD: nd6_nbr.c,v 1.92 2015/08/24 15:58:35 mpi Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
@@ -1128,15 +1128,14 @@ nd6_dad_stoptimer(struct dadq *dp)
/*
* Start Duplicated Address Detection (DAD) for specified interface address.
- *
- * tick - minimum delay ticks for IFF_UP event
*/
void
-nd6_dad_start(struct ifaddr *ifa, int *tick)
+nd6_dad_start(struct ifaddr *ifa)
{
struct in6_ifaddr *ia6 = ifatoia6(ifa);
struct dadq *dp;
char addr[INET6_ADDRSTRLEN];
+ int s;
if (!dad_init) {
TAILQ_INIT(&dadq);
@@ -1149,31 +1148,15 @@ nd6_dad_start(struct ifaddr *ifa, int *tick)
* - DAD is disabled (ip6_dad_count == 0)
* - the interface address is anycast
*/
- if (!(ia6->ia6_flags & IN6_IFF_TENTATIVE)) {
- log(LOG_DEBUG,
- "nd6_dad_start: called with non-tentative address "
- "%s(%s)\n",
- inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr,
- addr, sizeof(addr)),
- ifa->ifa_ifp ? ifa->ifa_ifp->if_xname : "???");
- return;
- }
- if (ia6->ia6_flags & IN6_IFF_ANYCAST) {
- ia6->ia6_flags &= ~IN6_IFF_TENTATIVE;
- return;
- }
- if (!ip6_dad_count) {
+ KASSERT(ia6->ia6_flags & IN6_IFF_TENTATIVE);
+ if ((ia6->ia6_flags & IN6_IFF_ANYCAST) || (!ip6_dad_count)) {
ia6->ia6_flags &= ~IN6_IFF_TENTATIVE;
return;
}
- if (!ifa->ifa_ifp)
- panic("nd6_dad_start: ifa->ifa_ifp == NULL");
- if (!(ifa->ifa_ifp->if_flags & IFF_UP))
- return;
- if (nd6_dad_find(ifa) != NULL) {
- /* DAD already in progress */
+
+ /* DAD already in progress */
+ if (nd6_dad_find(ifa) != NULL)
return;
- }
dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT | M_ZERO);
if (dp == NULL) {
@@ -1185,6 +1168,8 @@ nd6_dad_start(struct ifaddr *ifa, int *tick)
return;
}
bzero(&dp->dad_timer_ch, sizeof(dp->dad_timer_ch));
+
+ s = splsoftnet();
TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
ip6_dad_pending++;
@@ -1202,21 +1187,10 @@ nd6_dad_start(struct ifaddr *ifa, int *tick)
dp->dad_count = ip6_dad_count;
dp->dad_ns_icount = dp->dad_na_icount = 0;
dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
- if (tick == NULL) {
- nd6_dad_ns_output(dp, ifa);
- nd6_dad_starttimer(dp,
- (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
- } else {
- int ntick;
-
- if (*tick == 0)
- ntick = arc4random_uniform(MAX_RTR_SOLICITATION_DELAY *
- hz);
- else
- ntick = *tick + arc4random_uniform(hz / 2);
- *tick = ntick;
- nd6_dad_starttimer(dp, ntick);
- }
+ nd6_dad_ns_output(dp, ifa);
+ nd6_dad_starttimer(dp,
+ (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
+ splx(s);
}
/*
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index aa88ae17302..bd06a1871b7 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_rtr.c,v 1.116 2015/08/19 13:27:38 bluhm Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.117 2015/08/24 15:58:35 mpi Exp $ */
/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
@@ -2082,7 +2082,7 @@ in6_ifadd(struct nd_prefix *pr, int privacy)
/* XXX: scope zone ID? */
- ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
+ ifra.ifra_flags |= IN6_IFF_AUTOCONF|IN6_IFF_TENTATIVE;
/* allocate ifaddr structure, link into chain, etc. */
s = splsoftnet();
@@ -2101,7 +2101,13 @@ in6_ifadd(struct nd_prefix *pr, int privacy)
}
/* this is always non-NULL */
- return (in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr));
+ ia6 = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
+
+ /* Perform DAD, if needed. */
+ if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
+ nd6_dad_start(&ia6->ia_ifa);
+
+ return (ia6);
}
int