Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Sep 2005 16:58:23 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 83847 for review
Message-ID:  <200509181658.j8IGwNV3052629@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=83847

Change 83847 by rwatson@rwatson_peppercorn on 2005/09/18 16:57:33

	First cut at cleaning up ifnet removal and multicast socket panics:
	
	Add in_ifdetach(), which matches in6_ifdetach(), which allows the
	protocol to perform early tear-down on the interface.
	
	Annotate that if_detach() needs careful consideration.
	
	Remove calls to in_pcbpurgeif0() in the handling of SIOCDIFADDR --
	this is not the place to detect interface removal!
	
	Invoke in_pcbpurgeif0() from in_ifdetach().

Affected files ...

.. //depot/projects/netsmp/src/sys/net/if.c#16 edit
.. //depot/projects/netsmp/src/sys/netinet/in.c#8 edit
.. //depot/projects/netsmp/src/sys/netinet/in.h#3 edit

Differences ...

==== //depot/projects/netsmp/src/sys/net/if.c#16 (text+ko) ====

@@ -600,6 +600,9 @@
 /*
  * Detach an interface, removing it from the
  * list of "active" interfaces and freeing the struct ifnet.
+ *
+ * XXXRW: There are some significant questions about event ordering, and
+ * how to prevent things from starting to use the interface during detach.
  */
 void
 if_detach(struct ifnet *ifp)
@@ -637,6 +640,10 @@
 
 	if_purgeaddrs(ifp);
 
+#ifdef INET
+	in_ifdetach(ifp);
+#endif
+
 #ifdef INET6
 	/*
 	 * Remove all IPv6 kernel structs related to ifp.  This should be done

==== //depot/projects/netsmp/src/sys/netinet/in.c#8 (text+ko) ====

@@ -459,14 +459,6 @@
 		 * a routing process they will come back.
 		 */
 		in_ifadown(&ia->ia_ifa, 1);
-		/*
-		 * XXX horrible hack to detect that we are being called
-		 * from if_detach()
-		 */
-		if (ifaddr_byindex(ifp->if_index) == NULL) {
-			in_pcbpurgeif0(&ripcbinfo, ifp);
-			in_pcbpurgeif0(&udbinfo, ifp);
-		}
 		EVENTHANDLER_INVOKE(ifaddr_event, ifp);
 		error = 0;
 		break;
@@ -1046,3 +1038,15 @@
 		igmp_leavegroup(&my_inm);
 	IN_MULTI_UNLOCK();
 }
+
+/*
+ * On interface removal, clean up IPv4 data structures hung off of the ifnet.
+ */
+void
+in_ifdetach(ifp)
+	struct ifnet *ifp;
+{
+
+	in_pcbpurgeif0(&ripcbinfo, ifp);
+	in_pcbpurgeif0(&udbinfo, ifp);
+}

==== //depot/projects/netsmp/src/sys/netinet/in.h#3 (text+ko) ====

@@ -572,6 +572,7 @@
 int	 in_localip(struct in_addr);
 char	*inet_ntoa(struct in_addr); /* in libkern */
 char	*inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
+void	 in_ifdetach(struct ifnet *);
 
 #define	in_hosteq(s, t)	((s).s_addr == (t).s_addr)
 #define	in_nullhost(x)	((x).s_addr == INADDR_ANY)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509181658.j8IGwNV3052629>