Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 Stop passing llinfo_nd6 to nd6_ns_output



details:   https://anonhg.NetBSD.org/src/rev/e1692e849e3b
branches:  trunk
changeset: 811834:e1692e849e3b
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Wed Nov 18 05:16:22 2015 +0000

description:
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

diffstat:

 sys/netinet6/nd6.c     |  40 ++++++++++++++++++++++++++++++++++++----
 sys/netinet6/nd6.h     |   4 ++--
 sys/netinet6/nd6_nbr.c |  21 +++------------------
 3 files changed, 41 insertions(+), 24 deletions(-)

diffs (146 lines):

diff -r b1e084818c6c -r e1692e849e3b sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Wed Nov 18 04:24:02 2015 +0000
+++ b/sys/netinet6/nd6.c        Wed Nov 18 05:16:22 2015 +0000
@@ -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 @@
        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 @@
        }
 
        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 @@
         * 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;
diff -r b1e084818c6c -r e1692e849e3b sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Wed Nov 18 04:24:02 2015 +0000
+++ b/sys/netinet6/nd6.h        Wed Nov 18 05:16:22 2015 +0000
@@ -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 @@
        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 *);
diff -r b1e084818c6c -r e1692e849e3b sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Wed Nov 18 04:24:02 2015 +0000
+++ b/sys/netinet6/nd6_nbr.c    Wed Nov 18 05:16:22 2015 +0000
@@ -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 @@
 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 @@
                 * - 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 {



Home | Main Index | Thread Index | Old Index