Module Name: src Committed By: ozaki-r Date: Wed Nov 18 05:16:22 UTC 2015
Modified Files: src/sys/netinet6: nd6.c nd6.h nd6_nbr.c Log Message: Stop passing llinfo_nd6 to nd6_ns_output This is a restructuring for coming changes to nd6 (replacing llinfo_nd6 with llentry). Once we have a lock of llinfo_nd6, we need to pass it to nd6_ns_output with holding the lock. However, in a function subsequent to nd6_ns_output, the llinfo_nd6 may be looked up, i.e., its lock would be acquired again. To avoid such a situation, pass only required data (in6_addr) to nd6_ns_output instead of passing whole llinfo_nd6. Inspired by FreeBSD To generate a diff of this commit: cvs rdiff -u -r1.178 -r1.179 src/sys/netinet6/nd6.c cvs rdiff -u -r1.66 -r1.67 src/sys/netinet6/nd6.h cvs rdiff -u -r1.110 -r1.111 src/sys/netinet6/nd6_nbr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet6/nd6.c diff -u src/sys/netinet6/nd6.c:1.178 src/sys/netinet6/nd6.c:1.179 --- src/sys/netinet6/nd6.c:1.178 Wed Nov 18 02:51:11 2015 +++ src/sys/netinet6/nd6.c Wed Nov 18 05:16:22 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.c,v 1.178 2015/11/18 02:51:11 ozaki-r Exp $ */ +/* $NetBSD: nd6.c,v 1.179 2015/11/18 05:16:22 ozaki-r Exp $ */ /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.178 2015/11/18 02:51:11 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.179 2015/11/18 05:16:22 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -430,6 +430,32 @@ nd6_llinfo_settimer(struct llinfo_nd6 *l splx(s); } +/* + * Gets source address of the first packet in hold queue + * and stores it in @src. + * Returns pointer to @src (if hold queue is not empty) or NULL. + */ +static struct in6_addr * +nd6_llinfo_get_holdsrc(struct llinfo_nd6 *ln, struct in6_addr *src) +{ + struct ip6_hdr *hip6; + + if (ln == NULL || ln->ln_hold == NULL) + return NULL; + + /* + * assuming every packet in ln_hold has the same IP header + */ + hip6 = mtod(ln->ln_hold, struct ip6_hdr *); + /* XXX pullup? */ + if (sizeof(*hip6) < ln->ln_hold->m_len) + *src = hip6->ip6_src; + else + src = NULL; + + return src; +} + static void nd6_llinfo_timer(void *arg) { @@ -535,8 +561,11 @@ nd6_llinfo_timer(void *arg) } if (send_ns) { + struct in6_addr src, *psrc; + nd6_llinfo_settimer(ln, (long)ndi->retrans * hz / 1000); - nd6_ns_output(ifp, daddr6, &dst->sin6_addr, ln, 0); + psrc = nd6_llinfo_get_holdsrc(ln, &src); + nd6_ns_output(ifp, daddr6, &dst->sin6_addr, psrc, 0); } KERNEL_UNLOCK_ONE(NULL); @@ -2384,10 +2413,13 @@ nd6_output(struct ifnet *ifp, struct ifn * INCOMPLETE state, send the first solicitation. */ if (!ND6_LLINFO_PERMANENT(ln) && ln->ln_asked == 0) { + struct in6_addr src, *psrc; + ln->ln_asked++; nd6_llinfo_settimer(ln, (long)ND_IFINFO(ifp)->retrans * hz / 1000); - nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0); + psrc = nd6_llinfo_get_holdsrc(ln, &src); + nd6_ns_output(ifp, NULL, &dst->sin6_addr, psrc, 0); } error = 0; goto exit; Index: src/sys/netinet6/nd6.h diff -u src/sys/netinet6/nd6.h:1.66 src/sys/netinet6/nd6.h:1.67 --- src/sys/netinet6/nd6.h:1.66 Fri Jul 17 02:21:08 2015 +++ src/sys/netinet6/nd6.h Wed Nov 18 05:16:22 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.h,v 1.66 2015/07/17 02:21:08 ozaki-r Exp $ */ +/* $NetBSD: nd6.h,v 1.67 2015/11/18 05:16:22 ozaki-r Exp $ */ /* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */ /* @@ -439,7 +439,7 @@ void nd6_na_output(struct ifnet *, const const struct in6_addr *, u_long, int, const struct sockaddr *); void nd6_ns_input(struct mbuf *, int, int); void nd6_ns_output(struct ifnet *, const struct in6_addr *, - const struct in6_addr *, struct llinfo_nd6 *, int); + const struct in6_addr *, struct in6_addr *, int); const void *nd6_ifptomac(const struct ifnet *); void nd6_dad_start(struct ifaddr *, int); void nd6_dad_stop(struct ifaddr *); Index: src/sys/netinet6/nd6_nbr.c diff -u src/sys/netinet6/nd6_nbr.c:1.110 src/sys/netinet6/nd6_nbr.c:1.111 --- src/sys/netinet6/nd6_nbr.c:1.110 Mon Aug 24 22:21:27 2015 +++ src/sys/netinet6/nd6_nbr.c Wed Nov 18 05:16:22 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_nbr.c,v 1.110 2015/08/24 22:21:27 pooka Exp $ */ +/* $NetBSD: nd6_nbr.c,v 1.111 2015/11/18 05:16:22 ozaki-r Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.110 2015/08/24 22:21:27 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.111 2015/11/18 05:16:22 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -350,7 +350,7 @@ nd6_ns_input(struct mbuf *m, int off, in void nd6_ns_output(struct ifnet *ifp, const struct in6_addr *daddr6, const struct in6_addr *taddr6, - struct llinfo_nd6 *ln, /* for source address determination */ + struct in6_addr *hsrc, int dad /* duplicate address detection */) { struct mbuf *m; @@ -439,21 +439,6 @@ nd6_ns_output(struct ifnet *ifp, const s * - hsrc belongs to the outgoing interface. * Otherwise, we perform the source address selection as usual. */ - struct ip6_hdr *hip6; /* hold ip6 */ - struct in6_addr *hsrc = NULL; - - if (ln && ln->ln_hold) { - /* - * assuming every packet in ln_hold has the same IP - * header - */ - hip6 = mtod(ln->ln_hold, struct ip6_hdr *); - /* XXX pullup? */ - if (sizeof(*hip6) < ln->ln_hold->m_len) - hsrc = &hip6->ip6_src; - else - hsrc = NULL; - } if (hsrc && in6ifa_ifpwithaddr(ifp, hsrc)) src = hsrc; else {