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

assorted route diffs



last gem from a train ride to frankfurt a bit over a week ago... 
instead of re-implementing deletionion of routes associated with an 
to-be-removed interface, introduce rt_if_remove. pls read carefully & 
test.

Index: if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.144
diff -u -p -r1.144 if.c
--- if.c	4 Mar 2006 22:40:15 -0000	1.144
+++ if.c	6 Mar 2006 13:41:33 -0000
@@ -126,7 +126,6 @@
 
 void	if_attachsetup(struct ifnet *);
 void	if_attachdomain1(struct ifnet *);
-int	if_detach_rtdelete(struct radix_node *, void *);
 
 int	ifqmaxlen = IFQ_MAXLEN;
 
@@ -459,37 +458,6 @@ if_attach(struct ifnet *ifp)
 }
 
 /*
- * Delete a route if it has a specific interface for output.
- * This function complies to the rn_walktree callback API.
- *
- * Note that deleting a RTF_CLONING route can trigger the
- * deletion of more entries, so we need to cancel the walk
- * and return EAGAIN.  The caller should restart the walk
- * as long as EAGAIN is returned.
- */
-int
-if_detach_rtdelete(struct radix_node *rn, void *vifp)
-{
-	struct ifnet *ifp = vifp;
-	struct rtentry *rt = (struct rtentry *)rn;
-
-	if (rt->rt_ifp == ifp) {
-		int cloning = (rt->rt_flags & RTF_CLONING);
-
-		if (rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
-		    rt_mask(rt), 0, NULL) == 0 && cloning)
-			return (EAGAIN);
-	}
-
-	/*
-	 * XXX There should be no need to check for rt_ifa belonging to this
-	 * interface, because then rt_ifp is set, right?
-	 */
-
-	return (0);
-}
-
-/*
  * Detach an interface from everything in the kernel.  Also deallocate
  * private resources.
  * XXX So far only the INET protocol family has been looked over
@@ -500,8 +468,7 @@ if_detach(struct ifnet *ifp)
 {
 	struct ifaddr *ifa;
 	struct ifg_list *ifg;
-	int i, s = splnet();
-	struct radix_node_head *rnh;
+	int s = splnet();
 	struct domain *dp;
 
 	ifp->if_flags &= ~IFF_OACTIVE;
@@ -539,19 +506,7 @@ if_detach(struct ifnet *ifp)
 	if (ALTQ_IS_ATTACHED(&ifp->if_snd))
 		altq_detach(&ifp->if_snd);
 #endif
-
-	/*
-	 * Find and remove all routes which is using this interface.
-	 * XXX Factor out into a route.c function?
-	 */
-	for (i = 1; i <= AF_MAX; i++) {
-		rnh = rt_tables[i];
-		if (rnh)
-			while ((*rnh->rnh_walktree)(rnh,
-			    if_detach_rtdelete, ifp) == EAGAIN)
-				;
-	}
-
+	rt_if_remove(ifp);
 #ifdef INET
 	rti_delete(ifp);
 #if NETHER > 0
Index: if_tun.c
===================================================================
RCS file: /cvs/src/sys/net/if_tun.c,v
retrieving revision 1.76
diff -u -p -r1.76 if_tun.c
--- if_tun.c	5 Mar 2006 02:35:38 -0000	1.76
+++ if_tun.c	6 Mar 2006 13:41:34 -0000
@@ -347,10 +347,9 @@ int
 tunclose(dev_t dev, int flag, int mode, struct proc *p)
 {
 	extern int if_detach_rtdelete(struct radix_node *, void *);
-	int			 s, i;
+	int			 s;
 	struct tun_softc	*tp;
 	struct ifnet		*ifp;
-	struct radix_node_head	*rnh;
 
 	if ((tp = tun_lookup(minor(dev))) == NULL)
 		return (ENXIO);
@@ -382,17 +381,8 @@ tunclose(dev_t dev, int flag, int mode, 
 				/* XXX INET6 */
 #endif
 			}
-			/*
-			 * Find and remove all routes which is using this
-			 * interface. Stolen from if.c if_detach().
-			 */
-			for (i = 1; i <= AF_MAX; i++) {
-				rnh = rt_tables[i];
-				if (rnh)
-					while ((*rnh->rnh_walktree)(rnh,
-					    if_detach_rtdelete, ifp) == EAGAIN)
-						;
-			}
+
+			rt_if_remove(ifp);
 			ifp->if_flags &= ~IFF_RUNNING;
 		}
 		splx(s);
Index: route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.68
diff -u -p -r1.68 route.c
--- route.c	6 Mar 2006 13:36:03 -0000	1.68
+++ route.c	6 Mar 2006 13:41:34 -0000
@@ -144,6 +144,7 @@ int	okaytoclone(u_int, int);
 int	rtdeletemsg(struct rtentry *);
 int	rtflushclone1(struct radix_node *, void *);
 void	rtflushclone(struct radix_node_head *, struct rtentry *);
+int	rt_if_remove_rtdelete(struct radix_node *, void *);
 
 #define	LABELID_MAX	50000
 
@@ -1229,4 +1230,47 @@ rtlabel_unref(u_int16_t id)
 			break;
 		}
 	}
+}
+
+void
+rt_if_remove(struct ifnet *ifp)
+{
+	int			 i;
+	struct radix_node_head	*rnh;
+
+	for (i = 1; i <= AF_MAX; i++) {
+		rnh = rt_tables[i];
+		if (rnh)
+			while ((*rnh->rnh_walktree)(rnh,
+			    rt_if_remove_rtdelete, ifp) == EAGAIN)
+				;
+	}
+}
+
+/*
+ * Note that deleting a RTF_CLONING route can trigger the
+ * deletion of more entries, so we need to cancel the walk
+ * and return EAGAIN.  The caller should restart the walk
+ * as long as EAGAIN is returned.
+ */
+int
+rt_if_remove_rtdelete(struct radix_node *rn, void *vifp)
+{
+	struct ifnet	*ifp = vifp;
+	struct rtentry	*rt = (struct rtentry *)rn;
+
+	if (rt->rt_ifp == ifp) {
+		int	cloning = (rt->rt_flags & RTF_CLONING);
+
+		if (rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
+		    rt_mask(rt), 0, NULL) == 0 && cloning)
+			return (EAGAIN);
+	}
+
+	/*
+	 * XXX There should be no need to check for rt_ifa belonging to this
+	 * interface, because then rt_ifp is set, right?
+	 */
+
+	return (0);
 }
Index: route.h
===================================================================
RCS file: /cvs/src/sys/net/route.h,v
retrieving revision 1.35
diff -u -p -r1.35 route.h
--- route.h	23 Feb 2006 14:15:53 -0000	1.35
+++ route.h	6 Mar 2006 13:41:34 -0000
@@ -351,6 +351,7 @@ int	 rtrequest(int, struct sockaddr *,
 			struct sockaddr *, struct sockaddr *, int,
 			struct rtentry **);
 int	 rtrequest1(int, struct rt_addrinfo *, struct rtentry **);
+void	 rt_if_remove(struct ifnet *);
 
 #endif /* _KERNEL */
 #endif /* _NET_ROUTE_H_ */



Visit your host, monkey.org