diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-06-28 18:50:38 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-06-28 18:50:38 +0000 |
commit | 22b0156759c053e251b29ef230ddf75b9e45d9f4 (patch) | |
tree | 58fbb22339399962bcb296ceb830e2d267c226a7 /sys | |
parent | f668ba96c8a5c3248f9ce4db53f92c7ef8e16f9c (diff) |
Add the rtable id as an argument to rn_walktree(). Functions like
rt_if_remove_rtdelete() need to know the table id to be able to correctly
remove nodes.
Problem found by Andrea Parazzini and analyzed by Martin Pelikán.
OK henning@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_subr.c | 6 | ||||
-rw-r--r-- | sys/net/pf_table.c | 6 | ||||
-rw-r--r-- | sys/net/radix.c | 9 | ||||
-rw-r--r-- | sys/net/radix.h | 7 | ||||
-rw-r--r-- | sys/net/route.c | 31 | ||||
-rw-r--r-- | sys/net/route.h | 4 | ||||
-rw-r--r-- | sys/net/rtsock.c | 7 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 14 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 8 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 4 |
10 files changed, 52 insertions, 44 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 48d9b452e44..f6dd44b4bbe 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_subr.c,v 1.185 2010/05/06 06:53:09 mpf Exp $ */ +/* $OpenBSD: vfs_subr.c,v 1.186 2010/06/28 18:50:36 claudio Exp $ */ /* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */ /* @@ -103,7 +103,7 @@ int getdevvp(dev_t, struct vnode **, enum vtype); int vfs_hang_addrlist(struct mount *, struct netexport *, struct export_args *); -int vfs_free_netcred(struct radix_node *, void *); +int vfs_free_netcred(struct radix_node *, void *, u_int); void vfs_free_addrlist(struct netexport *); void vputonfreelist(struct vnode *); @@ -1482,7 +1482,7 @@ out: /* ARGSUSED */ int -vfs_free_netcred(struct radix_node *rn, void *w) +vfs_free_netcred(struct radix_node *rn, void *w, u_int id) { struct radix_node_head *rnh = (struct radix_node_head *)w; diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c index f46e053b20f..77a0e1d1e5c 100644 --- a/sys/net/pf_table.c +++ b/sys/net/pf_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_table.c,v 1.83 2010/02/24 15:04:40 henning Exp $ */ +/* $OpenBSD: pf_table.c,v 1.84 2010/06/28 18:50:37 claudio Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -156,7 +156,7 @@ int pfr_route_kentry(struct pfr_ktable *, struct pfr_kentry *); int pfr_unroute_kentry(struct pfr_ktable *, struct pfr_kentry *); -int pfr_walktree(struct radix_node *, void *); +int pfr_walktree(struct radix_node *, void *, u_int); int pfr_validate_table(struct pfr_table *, int, int); int pfr_fix_anchor(char *); void pfr_commit_ktable(struct pfr_ktable *, long); @@ -1066,7 +1066,7 @@ pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke) } int -pfr_walktree(struct radix_node *rn, void *arg) +pfr_walktree(struct radix_node *rn, void *arg, u_int id) { struct pfr_kentry *ke = (struct pfr_kentry *)rn; struct pfr_walktree *w = arg; diff --git a/sys/net/radix.c b/sys/net/radix.c index dd6e6a8748f..9ee6c10dd06 100644 --- a/sys/net/radix.c +++ b/sys/net/radix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radix.c,v 1.26 2009/01/06 21:40:47 claudio Exp $ */ +/* $OpenBSD: radix.c,v 1.27 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: radix.c,v 1.20 2003/08/07 16:32:56 agc Exp $ */ /* @@ -950,8 +950,8 @@ out: } int -rn_walktree(struct radix_node_head *h, int (*f)(struct radix_node *, void *), - void *w) +rn_walktree(struct radix_node_head *h, int (*f)(struct radix_node *, void *, + u_int), void *w) { int error; struct radix_node *base, *next; @@ -976,7 +976,8 @@ rn_walktree(struct radix_node_head *h, int (*f)(struct radix_node *, void *), /* Process leaves */ while ((rn = base) != NULL) { base = rn->rn_dupedkey; - if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w))) + if (!(rn->rn_flags & RNF_ROOT) && + (error = (*f)(rn, w, h->rnh_rtabelid))) return (error); } rn = next; diff --git a/sys/net/radix.h b/sys/net/radix.h index 60259b0fab1..fc7c867a05d 100644 --- a/sys/net/radix.h +++ b/sys/net/radix.h @@ -1,4 +1,4 @@ -/* $OpenBSD: radix.h,v 1.15 2008/11/07 19:09:03 deraadt Exp $ */ +/* $OpenBSD: radix.h,v 1.16 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: radix.h,v 1.8 1996/02/13 22:00:37 christos Exp $ */ /* @@ -125,9 +125,10 @@ struct radix_node_head { struct radix_node_head *head); /* traverse tree */ int (*rnh_walktree)(struct radix_node_head *, - int (*)(struct radix_node *, void *), void *); + int (*)(struct radix_node *, void *, u_int), void *); struct radix_node rnh_nodes[3];/* empty tree for common case */ int rnh_multipath; /* multipath? */ + u_int rnh_rtabelid; }; #ifdef _KERNEL @@ -142,7 +143,7 @@ int rn_inithead(void **, int); int rn_inithead0(struct radix_node_head *, int); int rn_refines(void *, void *); int rn_walktree(struct radix_node_head *, - int (*)(struct radix_node *, void *), void *); + int (*)(struct radix_node *, void *, u_int), void *); struct radix_node *rn_addmask(void *, int, int); struct radix_node *rn_addroute(void *, void *, struct radix_node_head *, diff --git a/sys/net/route.c b/sys/net/route.c index 121cb902565..c8497bf0dad 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.119 2010/06/04 11:05:13 blambert Exp $ */ +/* $OpenBSD: route.c,v 1.120 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -147,11 +147,11 @@ int rttrash; /* routes not in table but not freed */ struct pool rtentry_pool; /* pool for rtentry structures */ struct pool rttimer_pool; /* pool for rttimer structures */ -int rtable_init(struct radix_node_head ***); +int rtable_init(struct radix_node_head ***, u_int); int okaytoclone(u_int, int); -int rtflushclone1(struct radix_node *, void *); +int rtflushclone1(struct radix_node *, void *, u_int); void rtflushclone(struct radix_node_head *, struct rtentry *); -int rt_if_remove_rtdelete(struct radix_node *, void *); +int rt_if_remove_rtdelete(struct radix_node *, void *, u_int); #define LABELID_MAX 50000 @@ -173,10 +173,11 @@ encap_findgwifa(struct sockaddr *gw) #endif int -rtable_init(struct radix_node_head ***table) +rtable_init(struct radix_node_head ***table, u_int id) { void **p; struct domain *dom; + u_int8_t i; if ((p = malloc(sizeof(void *) * (rtafidx_max + 1), M_RTABLE, M_NOWAIT|M_ZERO)) == NULL) @@ -189,11 +190,17 @@ rtable_init(struct radix_node_head ***table) dom->dom_rtoffset); *table = (struct radix_node_head **)p; + + for (i = 0; i < rtafidx_max; i++) { + if ((*table)[i] != NULL) + (*table)[i]->rnh_rtabelid = id; + } + return (0); } void -route_init() +route_init(void) { struct domain *dom; @@ -246,7 +253,7 @@ rtable_add(u_int id) /* must be called at splsoftnet */ return (-1); rt_tab2dom[id] = 0; /* use main table/domain by default */ - return (rtable_init(&rt_tables[id])); + return (rtable_init(&rt_tables[id], id)); } u_int @@ -553,14 +560,14 @@ rtdeletemsg(struct rtentry *rt, u_int tableid) } int -rtflushclone1(struct radix_node *rn, void *arg) +rtflushclone1(struct radix_node *rn, void *arg, u_int id) { struct rtentry *rt, *parent; rt = (struct rtentry *)rn; parent = (struct rtentry *)arg; if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent == parent) - rtdeletemsg(rt, 0); + rtdeletemsg(rt, id); return 0; } @@ -1430,7 +1437,7 @@ rt_if_remove(struct ifnet *ifp) * as long as EAGAIN is returned. */ int -rt_if_remove_rtdelete(struct radix_node *rn, void *vifp) +rt_if_remove_rtdelete(struct radix_node *rn, void *vifp, u_int id) { struct ifnet *ifp = vifp; struct rtentry *rt = (struct rtentry *)rn; @@ -1438,7 +1445,7 @@ rt_if_remove_rtdelete(struct radix_node *rn, void *vifp) if (rt->rt_ifp == ifp) { int cloning = (rt->rt_flags & RTF_CLONING); - if (rtdeletemsg(rt, ifp->if_rdomain /* XXX wrong */) == 0 && cloning) + if (rtdeletemsg(rt, id) == 0 && cloning) return (EAGAIN); } @@ -1475,7 +1482,7 @@ rt_if_track(struct ifnet *ifp) } int -rt_if_linkstate_change(struct radix_node *rn, void *arg) +rt_if_linkstate_change(struct radix_node *rn, void *arg, u_int id) { struct ifnet *ifp = arg; struct rtentry *rt = (struct rtentry *)rn; diff --git a/sys/net/route.h b/sys/net/route.h index ac26efb31d3..668d0b7a437 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.68 2010/05/07 13:33:16 claudio Exp $ */ +/* $OpenBSD: route.h,v 1.69 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -400,7 +400,7 @@ int rtrequest1(int, struct rt_addrinfo *, u_int8_t, struct rtentry **, void rt_if_remove(struct ifnet *); #ifndef SMALL_KERNEL void rt_if_track(struct ifnet *); -int rt_if_linkstate_change(struct radix_node *, void *); +int rt_if_linkstate_change(struct radix_node *, void *, u_int); #endif int rtdeletemsg(struct rtentry *, u_int); diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 4dff661d0b3..2c9afdf3887 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.100 2010/05/19 13:09:09 claudio Exp $ */ +/* $OpenBSD: rtsock.c,v 1.101 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -648,7 +648,7 @@ report: #ifndef SMALL_KERNEL /* recheck link state after ifp change */ rt_if_linkstate_change( - (struct radix_node *)rt, ifp); + (struct radix_node *)rt, ifp, tableid); #endif } } @@ -1104,7 +1104,7 @@ rt_ifannouncemsg(struct ifnet *ifp, int what) * This is used in dumping the kernel table via sysctl(). */ int -sysctl_dumpentry(struct radix_node *rn, void *v) +sysctl_dumpentry(struct radix_node *rn, void *v, u_int id) { struct walkarg *w = v; struct rtentry *rt = (struct rtentry *)rn; @@ -1163,6 +1163,7 @@ sysctl_dumpentry(struct radix_node *rn, void *v) rtm->rtm_rmx.rmx_refcnt = rt->rt_refcnt; rtm->rtm_index = rt->rt_ifp->if_index; rtm->rtm_addrs = info.rti_addrs; + rtm->rtm_tableid = id; #ifdef MPLS rtm->rtm_mpls = info.rti_mpls; #endif diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index b0990f0851e..1de611baca5 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.86 2010/05/07 13:33:16 claudio Exp $ */ +/* $OpenBSD: if_ether.c,v 1.87 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -105,7 +105,7 @@ struct ifnet *myip_ifp; void db_print_sa(struct sockaddr *); void db_print_ifa(struct ifaddr *); void db_print_llinfo(caddr_t); -int db_show_radix_node(struct radix_node *, void *); +int db_show_radix_node(struct radix_node *, void *, u_int); #endif /* @@ -1106,16 +1106,14 @@ db_print_llinfo(li) * Return non-zero error to abort walk. */ int -db_show_radix_node(rn, w) - struct radix_node *rn; - void *w; +db_show_radix_node(struct radix_node *rn, void *w, u_int id) { struct rtentry *rt = (struct rtentry *)rn; db_printf("rtentry=%p", rt); - db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n", - rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire); + db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld rtableid %u\n", + rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire, id); db_printf(" key="); db_print_sa(rt_key(rt)); db_printf(" mask="); db_print_sa(rt_mask(rt)); @@ -1142,7 +1140,7 @@ db_show_radix_node(rn, w) * Use this from ddb: "call db_show_arptab" */ int -db_show_arptab() +db_show_arptab(void) { struct radix_node_head *rnh; rnh = rt_gettable(AF_INET, 0); diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index c882331c078..bac41ffbc10 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.52 2010/04/06 14:12:10 stsp Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.53 2010/06/28 18:50:37 claudio Exp $ */ /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* @@ -74,7 +74,7 @@ void purge_detached(struct ifnet *); void in6_init_address_ltimes(struct nd_prefix *, struct in6_addrlifetime *); -int rt6_deleteroute(struct radix_node *, void *); +int rt6_deleteroute(struct radix_node *, void *, u_int); extern int nd6_recalc_reachtm_interval; @@ -1907,7 +1907,7 @@ rt6_flush(struct in6_addr *gateway, struct ifnet *ifp) } int -rt6_deleteroute(struct radix_node *rn, void *arg) +rt6_deleteroute(struct radix_node *rn, void *arg, u_int id) { #define SIN6(s) ((struct sockaddr_in6 *)s) struct rt_addrinfo info; @@ -1940,7 +1940,7 @@ rt6_deleteroute(struct radix_node *rn, void *arg) info.rti_info[RTAX_DST] = rt_key(rt); info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; info.rti_info[RTAX_NETMASK] = rt_mask(rt); - return (rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, NULL, 0)); + return (rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, NULL, id)); #undef SIN6 } diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index abfe014b63d..4a53b096621 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.102 2010/05/02 00:51:10 tedu Exp $ */ +/* $OpenBSD: sysctl.h,v 1.103 2010/06/28 18:50:37 claudio Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -942,7 +942,7 @@ int sysctl_file2(int *, u_int, char *, size_t *, struct proc *); int sysctl_doproc(int *, u_int, char *, size_t *); struct radix_node; struct walkarg; -int sysctl_dumpentry(struct radix_node *, void *); +int sysctl_dumpentry(struct radix_node *, void *, u_int); int sysctl_iflist(int, struct walkarg *); int sysctl_rtable(int *, u_int, void *, size_t *, void *, size_t); int sysctl_clockrate(char *, size_t *, void *); |