Source-Changes-HG archive

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

[src/trunk]: src/sys Make sure to free all interface addresses in if_detach



details:   https://anonhg.NetBSD.org/src/rev/ff867dda4758
branches:  trunk
changeset: 346195:ff867dda4758
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Fri Jul 01 05:22:33 2016 +0000

description:
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

diffstat:

 sys/net/if.c           |   8 ++++----
 sys/net/route.c        |  21 +++++++++++++++++++--
 sys/netinet/if_arp.c   |   6 +++---
 sys/netinet6/nd6_nbr.c |   6 +++---
 4 files changed, 29 insertions(+), 12 deletions(-)

diffs (146 lines):

diff -r 2bfa78dd2857 -r ff867dda4758 sys/net/if.c
--- a/sys/net/if.c      Fri Jul 01 05:15:40 2016 +0000
+++ b/sys/net/if.c      Fri Jul 01 05:22:33 2016 +0000
@@ -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 @@
 
        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 @@
        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);
diff -r 2bfa78dd2857 -r ff867dda4758 sys/net/route.c
--- a/sys/net/route.c   Fri Jul 01 05:15:40 2016 +0000
+++ b/sys/net/route.c   Fri Jul 01 05:22:33 2016 +0000
@@ -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 @@
     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 @@
                        rt->rt_refcnt++;
                        rtfree(rt);
                }
+               rtcache_clear_rtentry(dst->sa_family, rt);
                break;
 
        case RTM_ADD:
@@ -1388,6 +1390,21 @@
 }
 
 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);
diff -r 2bfa78dd2857 -r ff867dda4758 sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c      Fri Jul 01 05:15:40 2016 +0000
+++ b/sys/netinet/if_arp.c      Fri Jul 01 05:22:33 2016 +0000
@@ -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 @@
 arp_dad_stoptimer(struct dadq *dp)
 {
 
-       callout_stop(&dp->dad_timer_ch);
+       callout_halt(&dp->dad_timer_ch, NULL);
 }
 
 static void
diff -r 2bfa78dd2857 -r ff867dda4758 sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Fri Jul 01 05:15:40 2016 +0000
+++ b/sys/netinet6/nd6_nbr.c    Fri Jul 01 05:22:33 2016 +0000
@@ -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 @@
 nd6_dad_stoptimer(struct dadq *dp)
 {
 
-       callout_stop(&dp->dad_timer_ch);
+       callout_halt(&dp->dad_timer_ch, NULL);
 }
 
 /*



Home | Main Index | Thread Index | Old Index