Module Name: src
Committed By: ozaki-r
Date: Thu Jul 28 09:03:51 UTC 2016
Modified Files:
src/sys/netinet: if_arp.c in.c
src/sys/netinet6: in6.c nd6_nbr.c
Log Message:
Fix panic on adding/deleting IP addresses under network load
Adding and deleting IP addresses aren't serialized with other network
opeartions, e.g., forwarding packets. So if we add or delete an IP
address under network load, a kernel panic may happen on manipulating
network-related shared objects such as rtentry and rtcache.
To avoid such panicks, we still need to hold softnet_lock in in_control
and in6_control that are called via ioctl and do network-related operations
including IP address additions/deletions.
Fix PR kern/51356
To generate a diff of this commit:
cvs rdiff -u -r1.219 -r1.220 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.176 -r1.177 src/sys/netinet/in.c
cvs rdiff -u -r1.211 -r1.212 src/sys/netinet6/in6.c
cvs rdiff -u -r1.125 -r1.126 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/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.219 src/sys/netinet/if_arp.c:1.220
--- src/sys/netinet/if_arp.c:1.219 Mon Jul 25 04:21:19 2016
+++ src/sys/netinet/if_arp.c Thu Jul 28 09:03:50 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arp.c,v 1.219 2016/07/25 04:21:19 ozaki-r Exp $ */
+/* $NetBSD: if_arp.c,v 1.220 2016/07/28 09:03:50 ozaki-r Exp $ */
/*-
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.219 2016/07/25 04:21:19 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.220 2016/07/28 09:03:50 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -1505,7 +1505,7 @@ static void
arp_dad_stoptimer(struct dadq *dp)
{
- callout_halt(&dp->dad_timer_ch, NULL);
+ callout_halt(&dp->dad_timer_ch, softnet_lock);
}
static void
Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.176 src/sys/netinet/in.c:1.177
--- src/sys/netinet/in.c:1.176 Wed Jul 20 03:36:51 2016
+++ src/sys/netinet/in.c Thu Jul 28 09:03:50 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: in.c,v 1.176 2016/07/20 03:36:51 ozaki-r Exp $ */
+/* $NetBSD: in.c,v 1.177 2016/07/28 09:03:50 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.176 2016/07/20 03:36:51 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.177 2016/07/28 09:03:50 ozaki-r Exp $");
#include "arp.h"
@@ -360,8 +360,8 @@ in_len2mask(struct in_addr *mask, u_int
* Ifp is 0 if not an interface-specific ioctl.
*/
/* ARGSUSED */
-int
-in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
+static int
+in_control0(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
{
struct ifreq *ifr = (struct ifreq *)data;
struct in_ifaddr *ia = NULL;
@@ -667,6 +667,18 @@ in_control(struct socket *so, u_long cmd
return error;
}
+int
+in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
+{
+ int error;
+
+ mutex_enter(softnet_lock);
+ error = in_control0(so, cmd, data, ifp);
+ mutex_exit(softnet_lock);
+
+ return error;
+}
+
/* Add ownaddr as loopback rtentry. */
static void
in_ifaddlocal(struct ifaddr *ifa)
Index: src/sys/netinet6/in6.c
diff -u src/sys/netinet6/in6.c:1.211 src/sys/netinet6/in6.c:1.212
--- src/sys/netinet6/in6.c:1.211 Wed Jul 20 07:56:10 2016
+++ src/sys/netinet6/in6.c Thu Jul 28 09:03:50 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.c,v 1.211 2016/07/20 07:56:10 ozaki-r Exp $ */
+/* $NetBSD: in6.c,v 1.212 2016/07/28 09:03:50 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.211 2016/07/20 07:56:10 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.212 2016/07/28 09:03:50 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -751,7 +751,9 @@ in6_control(struct socket *so, u_long cm
}
s = splnet();
+ mutex_enter(softnet_lock);
error = in6_control1(so , cmd, data, ifp);
+ mutex_exit(softnet_lock);
splx(s);
return error;
}
Index: src/sys/netinet6/nd6_nbr.c
diff -u src/sys/netinet6/nd6_nbr.c:1.125 src/sys/netinet6/nd6_nbr.c:1.126
--- src/sys/netinet6/nd6_nbr.c:1.125 Mon Jul 25 04:21:20 2016
+++ src/sys/netinet6/nd6_nbr.c Thu Jul 28 09:03:50 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6_nbr.c,v 1.125 2016/07/25 04:21:20 ozaki-r Exp $ */
+/* $NetBSD: nd6_nbr.c,v 1.126 2016/07/28 09:03:50 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.125 2016/07/25 04:21:20 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.126 2016/07/28 09:03:50 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -1077,7 +1077,7 @@ static void
nd6_dad_stoptimer(struct dadq *dp)
{
- callout_halt(&dp->dad_timer_ch, NULL);
+ callout_halt(&dp->dad_timer_ch, softnet_lock);
}
/*