Source-Changes-HG archive

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

[src/trunk]: src/sys Protect mtudisc and redirect stuffs of icmp/icmp6 with m...



details:   https://anonhg.NetBSD.org/src/rev/f0cc67272d0a
branches:  trunk
changeset: 821688:f0cc67272d0a
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon Feb 13 07:18:20 2017 +0000

description:
Protect mtudisc and redirect stuffs of icmp/icmp6 with mutex

We have to run pr_init of icmp and icmp6 prior to tcp and tcp6 ones
for mutex initialization.

diffstat:

 sys/netinet/in_proto.c   |  24 ++++++++--------
 sys/netinet/ip_icmp.c    |  53 ++++++++++++++++++++++++-----------
 sys/netinet6/icmp6.c     |  70 ++++++++++++++++++++++++++++++++++++-----------
 sys/netinet6/in6_proto.c |  24 ++++++++--------
 4 files changed, 113 insertions(+), 58 deletions(-)

diffs (truncated from 448 to 300 lines):

diff -r c36040758682 -r f0cc67272d0a sys/netinet/in_proto.c
--- a/sys/netinet/in_proto.c    Mon Feb 13 06:38:45 2017 +0000
+++ b/sys/netinet/in_proto.c    Mon Feb 13 07:18:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_proto.c,v 1.120 2016/04/26 08:44:44 ozaki-r Exp $   */
+/*     $NetBSD: in_proto.c,v 1.121 2017/02/13 07:18:20 ozaki-r Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.120 2016/04/26 08:44:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.121 2017/02/13 07:18:20 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mrouting.h"
@@ -201,6 +201,16 @@
        .pr_slowtimo = ip_slowtimo,
        .pr_drain = ip_drainstub,
 },
+{      .pr_type = SOCK_RAW,
+       .pr_domain = &inetdomain,
+       .pr_protocol = IPPROTO_ICMP,
+       .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+       .pr_input = icmp_input,
+       .pr_ctlinput = rip_ctlinput,
+       .pr_ctloutput = rip_ctloutput,
+       .pr_usrreqs = &rip_usrreqs,
+       .pr_init = icmp_init,
+},
 {      .pr_type = SOCK_DGRAM,
        .pr_domain = &inetdomain,
        .pr_protocol = IPPROTO_UDP,
@@ -277,16 +287,6 @@
        .pr_ctloutput = rip_ctloutput,
        .pr_usrreqs = &rip_usrreqs,
 },
-{      .pr_type = SOCK_RAW,
-       .pr_domain = &inetdomain,
-       .pr_protocol = IPPROTO_ICMP,
-       .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,
-       .pr_input = icmp_input,
-       .pr_ctlinput = rip_ctlinput,
-       .pr_ctloutput = rip_ctloutput,
-       .pr_usrreqs = &rip_usrreqs,
-       .pr_init = icmp_init,
-},
 #ifdef GATEWAY
 {      .pr_domain = &inetdomain,
        .pr_protocol = IPPROTO_IP,
diff -r c36040758682 -r f0cc67272d0a sys/netinet/ip_icmp.c
--- a/sys/netinet/ip_icmp.c     Mon Feb 13 06:38:45 2017 +0000
+++ b/sys/netinet/ip_icmp.c     Mon Feb 13 07:18:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_icmp.c,v 1.157 2017/02/07 02:38:08 ozaki-r Exp $    */
+/*     $NetBSD: ip_icmp.c,v 1.158 2017/02/13 07:18:20 ozaki-r Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -94,7 +94,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.157 2017/02/07 02:38:08 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.158 2017/02/13 07:18:20 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ipsec.h"
@@ -171,6 +171,9 @@
 static int icmp_redirtimeout = 600;
 static struct rttimer_queue *icmp_redirect_timeout_q = NULL;
 
+/* Protect mtudisc and redirect stuffs */
+static kmutex_t icmp_mtx __cacheline_aligned;
+
 static void icmp_mtudisc_timeout(struct rtentry *, struct rttimer *);
 static void icmp_redirect_timeout(struct rtentry *, struct rttimer *);
 
@@ -186,14 +189,17 @@
 
        sysctl_netinet_icmp_setup(NULL);
 
+       mutex_init(&icmp_mtx, MUTEX_DEFAULT, IPL_NONE);
        /*
         * This is only useful if the user initializes redirtimeout to
         * something other than zero.
         */
+       mutex_enter(&icmp_mtx);
        if (icmp_redirtimeout != 0) {
                icmp_redirect_timeout_q =
                        rt_timer_queue_create(icmp_redirtimeout);
        }
+       mutex_exit(&icmp_mtx);
 
        icmpstat_percpu = percpu_alloc(sizeof(uint64_t) * ICMP_NSTATS);
        icmp_wqinput = wqinput_create("icmp", _icmp_input);
@@ -205,17 +211,23 @@
 void
 icmp_mtudisc_callback_register(void (*func)(struct in_addr))
 {
-       struct icmp_mtudisc_callback *mc;
+       struct icmp_mtudisc_callback *mc, *new;
 
+       new = kmem_alloc(sizeof(*mc), KM_SLEEP);
+
+       mutex_enter(&icmp_mtx);
        for (mc = LIST_FIRST(&icmp_mtudisc_callbacks); mc != NULL;
             mc = LIST_NEXT(mc, mc_list)) {
-               if (mc->mc_func == func)
+               if (mc->mc_func == func) {
+                       mutex_exit(&icmp_mtx);
+                       kmem_free(new, sizeof(*mc));
                        return;
+               }
        }
 
-       mc = kmem_alloc(sizeof(*mc), KM_SLEEP);
-       mc->mc_func = func;
-       LIST_INSERT_HEAD(&icmp_mtudisc_callbacks, mc, mc_list);
+       new->mc_func = func;
+       LIST_INSERT_HEAD(&icmp_mtudisc_callbacks, new, mc_list);
+       mutex_exit(&icmp_mtx);
 }
 
 /*
@@ -640,6 +652,7 @@
                rt = NULL;
                rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst),
                    NULL, RTF_GATEWAY | RTF_HOST, sintosa(&icmpgw), &rt);
+               mutex_enter(&icmp_mtx);
                if (rt != NULL && icmp_redirtimeout != 0) {
                        i = rt_timer_add(rt, icmp_redirect_timeout,
                                         icmp_redirect_timeout_q);
@@ -651,6 +664,7 @@
                                    IN_PRINT(buf, &icp->icmp_ip.ip_dst), i);
                        }
                }
+               mutex_exit(&icmp_mtx);
                if (rt != NULL)
                        rt_unref(rt);
 
@@ -1016,19 +1030,20 @@
        int error, tmp;
        struct sysctlnode node;
 
+       mutex_enter(&icmp_mtx);
+
        node = *rnode;
        node.sysctl_data = &tmp;
        tmp = icmp_redirtimeout;
        error = sysctl_lookup(SYSCTLFN_CALL(&node));
        if (error || newp == NULL)
-               return (error);
-       if (tmp < 0)
-               return (EINVAL);
+               goto out;
+       if (tmp < 0) {
+               error = EINVAL;
+               goto out;
+       }
        icmp_redirtimeout = tmp;
 
-       /* XXX NOMPSAFE still need softnet_lock */
-       mutex_enter(softnet_lock);
-
        /*
         * was it a *defined* side-effect that anyone even *reading*
         * this value causes these things to happen?
@@ -1045,10 +1060,10 @@
                icmp_redirect_timeout_q =
                    rt_timer_queue_create(icmp_redirtimeout);
        }
-
-       mutex_exit(softnet_lock);
-
-       return (0);
+       error = 0;
+out:
+       mutex_exit(&icmp_mtx);
+       return error;
 }
 
 static int
@@ -1175,9 +1190,11 @@
                rt = nrt;
        }
 
+       mutex_enter(&icmp_mtx);
        if (ip_mtudisc_timeout_q == NULL)
                ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout);
        error = rt_timer_add(rt, icmp_mtudisc_timeout, ip_mtudisc_timeout_q);
+       mutex_exit(&icmp_mtx);
        if (error) {
                rt_unref(rt);
                return;
@@ -1234,9 +1251,11 @@
         * Notify protocols that the MTU for this destination
         * has changed.
         */
+       mutex_enter(&icmp_mtx);
        for (mc = LIST_FIRST(&icmp_mtudisc_callbacks); mc != NULL;
             mc = LIST_NEXT(mc, mc_list))
                (*mc->mc_func)(faddr);
+       mutex_exit(&icmp_mtx);
 }
 
 /*
diff -r c36040758682 -r f0cc67272d0a sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c      Mon Feb 13 06:38:45 2017 +0000
+++ b/sys/netinet6/icmp6.c      Mon Feb 13 07:18:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: icmp6.c,v 1.208 2017/02/07 02:38:08 ozaki-r Exp $      */
+/*     $NetBSD: icmp6.c,v 1.209 2017/02/13 07:18:20 ozaki-r Exp $      */
 /*     $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.208 2017/02/07 02:38:08 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.209 2017/02/13 07:18:20 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -152,6 +152,9 @@
 static int icmp6_redirect_hiwat = -1;
 static int icmp6_redirect_lowat = -1;
 
+/* Protect mtudisc and redirect stuffs */
+static kmutex_t icmp6_mtx __cacheline_aligned;
+
 static void icmp6_errcount(u_int, int, int);
 static int icmp6_rip6_input(struct mbuf **, int);
 static int icmp6_ratelimit(const struct in6_addr *, const int, const int);
@@ -180,8 +183,12 @@
 
        sysctl_net_inet6_icmp6_setup(NULL);
        mld_init();
+
+       mutex_init(&icmp6_mtx, MUTEX_DEFAULT, IPL_NONE);
+       mutex_enter(&icmp6_mtx);
        icmp6_mtudisc_timeout_q = rt_timer_queue_create(pmtu_expire);
        icmp6_redirect_timeout_q = rt_timer_queue_create(icmp6_redirtimeout);
+       mutex_exit(&icmp6_mtx);
 
        icmp6stat_percpu = percpu_alloc(sizeof(uint64_t) * ICMP6_NSTATS);
 
@@ -253,17 +260,23 @@
 void
 icmp6_mtudisc_callback_register(void (*func)(struct in6_addr *))
 {
-       struct icmp6_mtudisc_callback *mc;
+       struct icmp6_mtudisc_callback *mc, *new;
 
+       new = kmem_alloc(sizeof(*mc), KM_SLEEP);
+
+       mutex_enter(&icmp6_mtx);
        for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL;
             mc = LIST_NEXT(mc, mc_list)) {
-               if (mc->mc_func == func)
+               if (mc->mc_func == func) {
+                       mutex_exit(&icmp6_mtx);
+                       kmem_free(new, sizeof(*mc));
                        return;
+               }
        }
 
-       mc = kmem_alloc(sizeof(*mc), KM_SLEEP);
-       mc->mc_func = func;
-       LIST_INSERT_HEAD(&icmp6_mtudisc_callbacks, mc, mc_list);
+       new->mc_func = func;
+       LIST_INSERT_HEAD(&icmp6_mtudisc_callbacks, new, mc_list);
+       mutex_exit(&icmp6_mtx);
 }
 
 /*
@@ -1146,10 +1159,13 @@
         * allow non-validated cases if memory is plenty, to make traffic
         * from non-connected pcb happy.
         */
+       mutex_enter(&icmp6_mtx);
        rtcount = rt_timer_count(icmp6_mtudisc_timeout_q);
        if (validated) {
-               if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat)
+               if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat) {
+                       mutex_exit(&icmp6_mtx);
                        return;
+               }
                else if (0 <= icmp6_mtudisc_lowat &&
                    rtcount > icmp6_mtudisc_lowat) {
                        /*
@@ -1157,9 +1173,12 @@
                         */
                }
        } else {
-               if (0 <= icmp6_mtudisc_lowat && rtcount > icmp6_mtudisc_lowat)
+               if (0 <= icmp6_mtudisc_lowat && rtcount > icmp6_mtudisc_lowat) {



Home | Main Index | Thread Index | Old Index