summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2006-03-20 10:03:50 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2006-03-20 10:03:50 +0000
commit375728e6480d46f7707b6d0d31ec44cc8ecca086 (patch)
tree17de4d555b804e2e7a51dc381d5b335c0a5f33db
parent31b7e2bdeb0dbb5a83a7f2a4e5db1b28dd448032 (diff)
introduce rt_if_remove which takes care of routing table updates for an
interface that is removed. use that from if.c and if_tun.c instead of re-implementing in the latter case. ok claudio
-rw-r--r--sys/net/if.c51
-rw-r--r--sys/net/if_tun.c19
-rw-r--r--sys/net/route.c46
-rw-r--r--sys/net/route.h3
4 files changed, 54 insertions, 65 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index ccc0093c184..7cd521cdb80 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.144 2006/03/04 22:40:15 brad Exp $ */
+/* $OpenBSD: if.c,v 1.145 2006/03/20 10:03:49 henning Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -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
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index e2bddf1183a..9ce9528390a 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tun.c,v 1.77 2006/03/16 09:30:54 claudio Exp $ */
+/* $OpenBSD: if_tun.c,v 1.78 2006/03/20 10:03:49 henning Exp $ */
/* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */
/*
@@ -346,11 +346,9 @@ tunopen(dev_t dev, int flag, int mode, struct proc *p)
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 +380,8 @@ tunclose(dev_t dev, int flag, int mode, struct proc *p)
/* 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);
diff --git a/sys/net/route.c b/sys/net/route.c
index a2a0a04c6f7..cdfb19120aa 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.68 2006/03/06 13:36:03 henning Exp $ */
+/* $OpenBSD: route.c,v 1.69 2006/03/20 10:03:49 henning Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -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
@@ -1230,3 +1231,46 @@ rtlabel_unref(u_int16_t id)
}
}
}
+
+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);
+}
diff --git a/sys/net/route.h b/sys/net/route.h
index 59a8d5f369f..0c4724e3dd3 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.35 2006/02/23 14:15:53 claudio Exp $ */
+/* $OpenBSD: route.h,v 1.36 2006/03/20 10:03:49 henning Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -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_ */