Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 Protect ia6_memberships by in6_ifaddr_lock



details:   https://anonhg.NetBSD.org/src/rev/1c0a9a01733b
branches:  trunk
changeset: 822118:1c0a9a01733b
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Thu Mar 02 05:27:39 2017 +0000

description:
Protect ia6_memberships by in6_ifaddr_lock

diffstat:

 sys/netinet6/in6.c     |  33 +++++++++++++++++++++++++++++++--
 sys/netinet6/in6_var.h |   3 ++-
 sys/netinet6/mld6.c    |  16 +++-------------
 3 files changed, 36 insertions(+), 16 deletions(-)

diffs (159 lines):

diff -r 8a759d0c2e91 -r 1c0a9a01733b sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Thu Mar 02 05:26:24 2017 +0000
+++ b/sys/netinet6/in6.c        Thu Mar 02 05:27:39 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.241 2017/03/01 03:02:35 ozaki-r Exp $        */
+/*     $NetBSD: in6.c,v 1.242 2017/03/02 05:27:39 ozaki-r Exp $        */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.241 2017/03/01 03:02:35 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.242 2017/03/02 05:27:39 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -825,7 +825,9 @@
                    IN6_PRINT(ip6buf, &llsol), if_name(ifp), error);
                goto out;
        }
+       mutex_enter(&in6_ifaddr_lock);
        LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+       mutex_exit(&in6_ifaddr_lock);
        *in6m_sol = imm->i6mm_maddr;
 
        sockaddr_in6_init(&mltmask, &in6mask32, 0, 0, 0);
@@ -887,7 +889,9 @@
                    if_name(ifp), error);
                goto out;
        }
+       mutex_enter(&in6_ifaddr_lock);
        LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+       mutex_exit(&in6_ifaddr_lock);
 
        /*
         * join node information group address
@@ -910,7 +914,9 @@
                    if_name(ifp), error);
                /* XXX not very fatal, go on... */
        } else {
+               mutex_enter(&in6_ifaddr_lock);
                LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+               mutex_exit(&in6_ifaddr_lock);
        }
 
 
@@ -967,7 +973,9 @@
                    if_name(ifp), error);
                goto out;
        } else {
+               mutex_enter(&in6_ifaddr_lock);
                LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+               mutex_exit(&in6_ifaddr_lock);
        }
        return 0;
 
@@ -1372,10 +1380,14 @@
        /*
         * leave from multicast groups we have joined for the interface
         */
+       mutex_enter(&in6_ifaddr_lock);
        while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
                LIST_REMOVE(imm, i6mm_chain);
+               mutex_exit(&in6_ifaddr_lock);
                in6_leavegroup(imm);
+               mutex_enter(&in6_ifaddr_lock);
        }
+       mutex_exit(&in6_ifaddr_lock);
 
        in6_unlink_ifa(ia, ifp);
 }
@@ -1427,6 +1439,23 @@
        in6_ifdetach(ifp);
 }
 
+void
+in6_purge_mcast_references(struct in6_multi *in6m)
+{
+       struct  in6_ifaddr *ia;
+
+       mutex_enter(&in6_ifaddr_lock);
+       IN6_ADDRLIST_WRITER_FOREACH(ia) {
+               struct in6_multi_mship *imm;
+               /* XXX imm isn't safe? */
+               LIST_FOREACH(imm, &ia->ia6_memberships, i6mm_chain) {
+                       if (imm->i6mm_maddr == in6m)
+                               imm->i6mm_maddr = NULL;
+               }
+       }
+       mutex_exit(&in6_ifaddr_lock);
+}
+
 /*
  * SIOC[GAD]LIFADDR.
  *     SIOCGLIFADDR: get first address. (?)
diff -r 8a759d0c2e91 -r 1c0a9a01733b sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h    Thu Mar 02 05:26:24 2017 +0000
+++ b/sys/netinet6/in6_var.h    Thu Mar 02 05:27:39 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_var.h,v 1.94 2017/03/01 08:54:12 ozaki-r Exp $     */
+/*     $NetBSD: in6_var.h,v 1.95 2017/03/02 05:27:39 ozaki-r Exp $     */
 /*     $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $        */
 
 /*
@@ -716,6 +716,7 @@
 int    in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int);
 void   in6_prefixlen2mask(struct in6_addr *, int);
 void   in6_purgeprefix(struct ifnet *);
+void   in6_purge_mcast_references(struct in6_multi *);
 
 int    ip6flow_fastforward(struct mbuf **); /* IPv6 fast forward routine */
 
diff -r 8a759d0c2e91 -r 1c0a9a01733b sys/netinet6/mld6.c
--- a/sys/netinet6/mld6.c       Thu Mar 02 05:26:24 2017 +0000
+++ b/sys/netinet6/mld6.c       Thu Mar 02 05:27:39 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mld6.c,v 1.85 2017/03/01 09:09:37 ozaki-r Exp $        */
+/*     $NetBSD: mld6.c,v 1.86 2017/03/02 05:27:39 ozaki-r Exp $        */
 /*     $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $   */
 
 /*
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.85 2017/03/01 09:09:37 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.86 2017/03/02 05:27:39 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -788,9 +788,7 @@
 static void
 in6m_destroy(struct in6_multi *in6m)
 {
-       struct  in6_ifaddr *ia;
        struct sockaddr_in6 sin6;
-       int s;
 
        KASSERT(rw_write_held(&in6_multilock));
        KASSERT(in6m->in6m_refcount == 0);
@@ -810,15 +808,7 @@
         * Delete all references of this multicasting group from
         * the membership arrays
         */
-       s = pserialize_read_enter();
-       IN6_ADDRLIST_READER_FOREACH(ia) {
-               struct in6_multi_mship *imm;
-               LIST_FOREACH(imm, &ia->ia6_memberships, i6mm_chain) {
-                       if (imm->i6mm_maddr == in6m)
-                               imm->i6mm_maddr = NULL;
-               }
-       }
-       pserialize_read_exit(s);
+       in6_purge_mcast_references(in6m);
 
        /*
         * Notify the network driver to update its multicast



Home | Main Index | Thread Index | Old Index