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/9cba16b937a9
branches: trunk
changeset: 351437:9cba16b937a9
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 e5eb40e6f585 -r 9cba16b937a9 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 e5eb40e6f585 -r 9cba16b937a9 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 e5eb40e6f585 -r 9cba16b937a9 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