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

more route diffs - needs eye and testing!



this is the more risky part, and inlcudes my previous diff.
this makes the routing table heads itself no longer globaly visible.
a route lookup function is provided, so that te various places that do 
lookups do not have to fiddle with radix callback semantics any longer, 
and a rt_gettable gives a node head to the few places that need the 
heads. this will allow us to change internals of the routing table 
stuff easier.

please read, test, comment.

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.144
diff -u -p -r1.144 if.c
--- net/if.c	4 Mar 2006 22:40:15 -0000	1.144
+++ net/if.c	6 Mar 2006 18:38:11 -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
@@ -1806,7 +1761,6 @@ if_group_egress_build(void)
 #ifdef INET6
 	struct sockaddr_in6	 sa_in6;
 #endif
-	struct radix_node_head	*rnh;
 	struct radix_node	*rn;
 	struct rtentry		*rt;
 
@@ -1820,42 +1774,34 @@ if_group_egress_build(void)
 			if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS);
 		}
 
-	if ((rnh = rt_tables[AF_INET]) == NULL)
-		return (-1);
-
 	bzero(&sa_in, sizeof(sa_in));
 	sa_in.sin_len = sizeof(sa_in);
 	sa_in.sin_family = AF_INET;
-	if ((rn = rnh->rnh_lookup(&sa_in, &sa_in, rnh))) {
+	if ((rn = rt_lookup(sintosa(&sa_in), sintosa(&sa_in), 0)) != NULL) {
 		do {
 			rt = (struct rtentry *)rn;
 			if (rt->rt_ifp)
 				if_addgroup(rt->rt_ifp, IFG_EGRESS);
 #ifndef SMALL_KERNEL
-			if (rn_mpath_capable(rnh))
-				rn = rn_mpath_next(rn);
-			else
+			rn = rn_mpath_next(rn);
+#else
+			rn = NULL;
 #endif
-				rn = NULL;
 		} while (rn != NULL);
 	}
 
 #ifdef INET6
-	if ((rnh = rt_tables[AF_INET6]) == NULL)
-		return (-1);
-
 	bcopy(&sa6_any, &sa_in6, sizeof(sa_in6));
-	if ((rn = rnh->rnh_lookup(&sa_in6, &sa_in6, rnh))) {
+	if ((rn = rt_lookup(sin6tosa(&sa_in6), sin6tosa(&sa_in6), 0)) != NULL) {
 		do {
 			rt = (struct rtentry *)rn;
 			if (rt->rt_ifp)
 				if_addgroup(rt->rt_ifp, IFG_EGRESS);
 #ifndef SMALL_KERNEL
-			if (rn_mpath_capable(rnh))
-				rn = rn_mpath_next(rn);
-			else
+			rn = rn_mpath_next(rn);
+#else
+			rn = NULL;
 #endif
-				rn = NULL;
 		} while (rn != NULL);
 	}
 #endif
Index: net/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
--- net/if_tun.c	5 Mar 2006 02:35:38 -0000	1.76
+++ net/if_tun.c	6 Mar 2006 18:38:12 -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: net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.68
diff -u -p -r1.68 route.c
--- net/route.c	6 Mar 2006 13:36:03 -0000	1.68
+++ net/route.c	6 Mar 2006 18:38:18 -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
 
@@ -1121,6 +1122,22 @@ rt_timer_add(struct rtentry *rt, void (*
 	return (0);
 }
 
+struct radix_node_head *
+rt_gettable(sa_family_t af, int id)
+{
+	/* ignore id for now */
+	return (rt_tables[af]);
+}
+
+struct radix_node *
+rt_lookup(struct sockaddr *dst, struct sockaddr *mask, int tableid)
+{
+	struct radix_node_head	*rnh;
+
+	rnh = rt_gettable(dst->sa_family, tableid);
+
+	return (rnh->rnh_lookup(dst, mask, rnh));
+}
 /* ARGSUSED */
 void
 rt_timer_timer(void *arg)
@@ -1229,4 +1246,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: net/route.h
===================================================================
RCS file: /cvs/src/sys/net/route.h,v
retrieving revision 1.35
diff -u -p -r1.35 route.h
--- net/route.h	23 Feb 2006 14:15:53 -0000	1.35
+++ net/route.h	6 Mar 2006 18:38:18 -0000
@@ -304,7 +304,6 @@ void		 rtlabel_unref(u_int16_t);
 
 extern struct route_cb route_cb;
 extern struct rtstat rtstat;
-extern struct radix_node_head *rt_tables[];
 extern const struct sockaddr_rtin rt_defmask4;
 
 struct	socket;
@@ -351,6 +350,10 @@ 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 *);
+
+struct radix_node_head	*rt_gettable(sa_family_t, int);
+struct radix_node	*rt_lookup(struct sockaddr *, struct sockaddr *, int);
 
 #endif /* _KERNEL */
 #endif /* _NET_ROUTE_H_ */
Index: net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.53
diff -u -p -r1.53 rtsock.c
--- net/rtsock.c	23 Feb 2006 14:15:53 -0000	1.53
+++ net/rtsock.c	6 Mar 2006 18:38:22 -0000
@@ -165,7 +165,9 @@ route_output(struct mbuf *m, ...)
 	struct radix_node	*rn = NULL;
 	struct rtentry		*rt = NULL;
 	struct rtentry		*saved_nrt = NULL;
+#ifndef SMALL_KERNEL
 	struct radix_node_head	*rnh;
+#endif
 	struct rt_addrinfo	 info;
 	int			 len, error = 0;
 	struct ifnet		*ifp = NULL;
@@ -263,11 +265,11 @@ route_output(struct mbuf *m, ...)
 	case RTM_GET:
 	case RTM_CHANGE:
 	case RTM_LOCK:
-		if ((rnh = rt_tables[dst->sa_family]) == 0) {
+		if (rt_gettable(dst->sa_family, 0) == NULL) {
 			error = EAFNOSUPPORT;
 			goto flush;
 		}
-		rn = rnh->rnh_lookup(dst, netmask, rnh);
+		rn = rt_lookup(dst, netmask, 0);
 		if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) {
 			error = ESRCH;
 			goto flush;
@@ -907,7 +909,7 @@ sysctl_rtable(int *name, u_int namelen, 
 	case NET_RT_DUMP:
 	case NET_RT_FLAGS:
 		for (i = 1; i <= AF_MAX; i++)
-			if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&
+			if ((rnh = rt_gettable(i, 0)) && (af == 0 || af == i) &&
 			    (error = (*rnh->rnh_walktree)(rnh,
 			    sysctl_dumpentry, &w)))
 				break;
Index: netinet/if_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.62
diff -u -p -r1.62 if_ether.c
--- netinet/if_ether.c	4 Mar 2006 22:40:16 -0000	1.62
+++ netinet/if_ether.c	6 Mar 2006 18:38:28 -0000
@@ -1077,7 +1077,7 @@ int
 db_show_arptab()
 {
 	struct radix_node_head *rnh;
-	rnh = rt_tables[AF_INET];
+	rnh = rt_gettable(AF_INET, 0);
 	db_printf("Route tree for AF_INET\n");
 	if (rnh == NULL) {
 		db_printf(" (not initialized)\n");
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.119
diff -u -p -r1.119 ip_carp.c
--- netinet/ip_carp.c	28 Jan 2006 23:47:20 -0000	1.119
+++ netinet/ip_carp.c	6 Mar 2006 18:38:32 -0000
@@ -340,10 +340,8 @@ carp_setroute(struct carp_softc *sc, int
 		case AF_INET: {
 			int count = 0;
 			struct sockaddr sa;
+			struct sockaddr_in mask;
 			struct rtentry *rt;
-			struct radix_node_head *rnh =
-			    rt_tables[ifa->ifa_addr->sa_family];
-			struct radix_node *rn;
 			int hr_otherif, nr_ourif;
 
 			/*
@@ -367,8 +365,9 @@ carp_setroute(struct carp_softc *sc, int
 			    RTF_HOST, NULL);
 
 			/* Check for our address on another interface */
-			rn = rnh->rnh_matchaddr(ifa->ifa_addr, rnh);
-			rt = (struct rtentry *)rn;
+			memset(&mask, 1, sizeof(mask));
+			rt = (struct rtentry *)rt_lookup(ifa->ifa_addr,
+			    sintosa(&mask), 0);
 			hr_otherif = (rt && rt->rt_ifp != &sc->sc_if &&
 			    rt->rt_flags & (RTF_CLONING|RTF_CLONED));
 
@@ -376,8 +375,9 @@ carp_setroute(struct carp_softc *sc, int
 			bcopy(ifa->ifa_addr, &sa, sizeof(sa));
 			satosin(&sa)->sin_addr.s_addr = satosin(ifa->ifa_netmask
 			    )->sin_addr.s_addr & satosin(&sa)->sin_addr.s_addr;
-			rn = rnh->rnh_lookup(&sa, ifa->ifa_netmask, rnh);
-			rt = (struct rtentry *)rn;
+			
+			rt = (struct rtentry *)rt_lookup(&sa,
+			    ifa->ifa_netmask, 0);
 			nr_ourif = (rt && rt->rt_ifp == &sc->sc_if);
 
 			switch (cmd) {
Index: netinet6/nd6_rtr.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v
retrieving revision 1.36
diff -u -p -r1.36 nd6_rtr.c
--- netinet6/nd6_rtr.c	5 Mar 2006 21:48:57 -0000	1.36
+++ netinet6/nd6_rtr.c	6 Mar 2006 18:38:42 -0000
@@ -1785,7 +1785,7 @@ rt6_flush(gateway, ifp)
     struct in6_addr *gateway;
     struct ifnet *ifp;
 {
-	struct radix_node_head *rnh = rt_tables[AF_INET6];
+	struct radix_node_head *rnh = rt_gettable(AF_INET6, 0);
 	int s = splsoftnet();
 
 	/* We'll care only link-local addresses */



Visit your host, monkey.org