diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2006-03-20 10:03:50 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2006-03-20 10:03:50 +0000 |
commit | 375728e6480d46f7707b6d0d31ec44cc8ecca086 (patch) | |
tree | 17de4d555b804e2e7a51dc381d5b335c0a5f33db /sys/net | |
parent | 31b7e2bdeb0dbb5a83a7f2a4e5db1b28dd448032 (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
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 51 | ||||
-rw-r--r-- | sys/net/if_tun.c | 19 | ||||
-rw-r--r-- | sys/net/route.c | 46 | ||||
-rw-r--r-- | sys/net/route.h | 3 |
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_ */ |