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 {

Reply via email to