Module Name: src
Committed By: ozaki-r
Date: Fri Jul 1 05:22:33 UTC 2016
Modified Files:
src/sys/net: if.c route.c
src/sys/netinet: if_arp.c
src/sys/netinet6: nd6_nbr.c
Log Message:
Make sure to free all interface addresses in if_detach
Addresses of an interface (struct ifaddr) have a (reverse) pointer of an
interface object (ifa->ifa_ifp). If the addresses are surely freed when
their interface is destroyed, the pointer is always valid and we don't
need a tweak of replacing the pointer to if_index like mbuf.
In order to make sure the assumption, the following changes are required:
- Deactivate the interface at the firstish of if_detach. This prevents
in6_unlink_ifa from saving multicast addresses (wrongly)
- Invalidate rtcache(s) and clear a rtentry referencing an address on
RTM_DELETE. rtcache(s) may delay freeing an address
- Replace callout_stop with callout_halt of DAD timers to ensure stopping
such timers in if_detach
To generate a diff of this commit:
cvs rdiff -u -r1.349 -r1.350 src/sys/net/if.c
cvs rdiff -u -r1.167 -r1.168 src/sys/net/route.c
cvs rdiff -u -r1.214 -r1.215 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.121 -r1.122 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/net/if.c
diff -u src/sys/net/if.c:1.349 src/sys/net/if.c:1.350
--- src/sys/net/if.c:1.349 Fri Jul 1 05:15:40 2016
+++ src/sys/net/if.c Fri Jul 1 05:22:33 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.349 2016/07/01 05:15:40 ozaki-r Exp $ */
+/* $NetBSD: if.c,v 1.350 2016/07/01 05:22:33 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.349 2016/07/01 05:15:40 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.350 2016/07/01 05:22:33 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -1117,7 +1117,7 @@ if_detach(struct ifnet *ifp)
sysctl_teardown(&ifp->if_sysctl_log);
mutex_enter(ifp->if_ioctl_lock);
- ifp->if_ioctl = if_nullioctl;
+ if_deactivate(ifp);
mutex_exit(ifp->if_ioctl_lock);
IFNET_LOCK();
@@ -1130,7 +1130,7 @@ if_detach(struct ifnet *ifp)
mutex_obj_free(ifp->if_ioctl_lock);
ifp->if_ioctl_lock = NULL;
- if (ifp->if_slowtimo != NULL) {
+ if (ifp->if_slowtimo != NULL && ifp->if_slowtimo_ch != NULL) {
ifp->if_slowtimo = NULL;
callout_halt(ifp->if_slowtimo_ch, NULL);
callout_destroy(ifp->if_slowtimo_ch);
Index: src/sys/net/route.c
diff -u src/sys/net/route.c:1.167 src/sys/net/route.c:1.168
--- src/sys/net/route.c:1.167 Thu Apr 28 00:16:56 2016
+++ src/sys/net/route.c Fri Jul 1 05:22:33 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: route.c,v 1.167 2016/04/28 00:16:56 ozaki-r Exp $ */
+/* $NetBSD: route.c,v 1.168 2016/07/01 05:22:33 ozaki-r Exp $ */
/*-
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.167 2016/04/28 00:16:56 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.168 2016/07/01 05:22:33 ozaki-r Exp $");
#include <sys/param.h>
#ifdef RTFLUSH_DEBUG
@@ -150,6 +150,7 @@ static void rt_maskedcopy(const struct s
struct sockaddr *, const struct sockaddr *);
static void rtcache_clear(struct route *);
+static void rtcache_clear_rtentry(int, struct rtentry *);
static void rtcache_invalidate(struct dom_rtlist *);
#ifdef DDB
@@ -794,6 +795,7 @@ rtrequest1(int req, struct rt_addrinfo *
rt->rt_refcnt++;
rtfree(rt);
}
+ rtcache_clear_rtentry(dst->sa_family, rt);
break;
case RTM_ADD:
@@ -1388,6 +1390,21 @@ rtcache_invalidate(struct dom_rtlist *rt
}
static void
+rtcache_clear_rtentry(int family, struct rtentry *rt)
+{
+ struct domain *dom;
+ struct route *ro;
+
+ if ((dom = pffinddomain(family)) == NULL)
+ return;
+
+ LIST_FOREACH(ro, &dom->dom_rtcache, ro_rtcache_next) {
+ if (ro->_ro_rt == rt)
+ rtcache_clear(ro);
+ }
+}
+
+static void
rtcache_clear(struct route *ro)
{
rtcache_invariants(ro);
Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.214 src/sys/netinet/if_arp.c:1.215
--- src/sys/netinet/if_arp.c:1.214 Thu Jun 30 01:34:53 2016
+++ src/sys/netinet/if_arp.c Fri Jul 1 05:22:33 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arp.c,v 1.214 2016/06/30 01:34:53 ozaki-r Exp $ */
+/* $NetBSD: if_arp.c,v 1.215 2016/07/01 05:22:33 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.214 2016/06/30 01:34:53 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.215 2016/07/01 05:22:33 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -1511,7 +1511,7 @@ static void
arp_dad_stoptimer(struct dadq *dp)
{
- callout_stop(&dp->dad_timer_ch);
+ callout_halt(&dp->dad_timer_ch, NULL);
}
static void
Index: src/sys/netinet6/nd6_nbr.c
diff -u src/sys/netinet6/nd6_nbr.c:1.121 src/sys/netinet6/nd6_nbr.c:1.122
--- src/sys/netinet6/nd6_nbr.c:1.121 Tue Jun 21 10:25:27 2016
+++ src/sys/netinet6/nd6_nbr.c Fri Jul 1 05:22:33 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6_nbr.c,v 1.121 2016/06/21 10:25:27 ozaki-r Exp $ */
+/* $NetBSD: nd6_nbr.c,v 1.122 2016/07/01 05:22:33 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.121 2016/06/21 10:25:27 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.122 2016/07/01 05:22:33 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -1074,7 +1074,7 @@ static void
nd6_dad_stoptimer(struct dadq *dp)
{
- callout_stop(&dp->dad_timer_ch);
+ callout_halt(&dp->dad_timer_ch, NULL);
}
/*