[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
more route diffs - needs eye and testing!
- To: tech_(_at_)_cvs_(_dot_)_openbsd_(_dot_)_org
- Subject: more route diffs - needs eye and testing!
- From: Henning Brauer <henning_(_at_)_openbsd_(_dot_)_org>
- Date: Mon, 6 Mar 2006 20:46:56 +0100
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