vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| 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 */ |
| Thread Tools | |
| Display Modes | |
|
|