diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_spppsubr.c | 5 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 37 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 37 | ||||
-rw-r--r-- | sys/netinet6/in6_var.h | 5 | ||||
-rw-r--r-- | sys/netinet6/nd6.h | 4 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 54 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 12 |
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 |