Subject: Re: fix for if_detach()
To: None <M.Drochner@fz-juelich.de>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: tech-net
Date: 11/10/2003 13:19:14
This is a multipart MIME message.

--==_Exmh_25751356150270
Content-Type: text/plain; charset=us-ascii


M.Drochner@fz-juelich.de said:
> The appended patch fixes the list walking. 

now really...



--==_Exmh_25751356150270
Content-Type: text/plain ; name="ifdet.txt"; charset=us-ascii
Content-Description: ifdet.txt
Content-Disposition: attachment; filename="ifdet.txt"

Index: if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.132
diff -u -p -r1.132 if.c
--- if.c	13 Oct 2003 08:02:56 -0000	1.132
+++ if.c	10 Nov 2003 11:51:46 -0000
@@ -543,7 +543,7 @@ if_detach(ifp)
 	struct ifnet *ifp;
 {
 	struct socket so;
-	struct ifaddr *ifa, *next;
+	struct ifaddr *ifa, **secondp;
 #ifdef IFAREF_DEBUG
 	struct ifaddr *last_ifa = NULL;
 #endif
@@ -580,8 +580,10 @@ if_detach(ifp)
 	 * Rip all the addresses off the interface.  This should make
 	 * all of the routes go away.
 	 */
-	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa; ifa = next) {
-		next = TAILQ_NEXT(ifa, ifa_list);
+	ifa = TAILQ_FIRST(&ifp->if_addrlist);
+	KASSERT(ifa->ifa_addr->sa_family == AF_LINK);
+	secondp = &TAILQ_NEXT(ifa, ifa_list); /* XXX abstraction violation */
+	while ((ifa = *secondp)) {
 		family = ifa->ifa_addr->sa_family;
 #ifdef IFAREF_DEBUG
 		printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
@@ -590,8 +592,7 @@ if_detach(ifp)
 			panic("if_detach: loop detected");
 		last_ifa = ifa;
 #endif
-		if (family == AF_LINK)
-			continue;
+		KASSERT(family != AF_LINK);
 		dp = pffinddomain(family);
 #ifdef DIAGNOSTIC
 		if (dp == NULL)
@@ -616,6 +617,7 @@ if_detach(ifp)
 			 */
 			printf("if_detach: WARNING: AF %d not purged\n",
 			    family);
+			TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
 		}
 	}
 

--==_Exmh_25751356150270--