diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-07-18 15:51:18 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-07-18 15:51:18 +0000 |
commit | 2271698f85393fb0d080c95f2232ce5bca8baf31 (patch) | |
tree | 8b799caea4e40a4941422811d640a5cf14608159 /sys | |
parent | cfe2dd9907ff6b16160feb76eff7dc874abe1c8e (diff) |
Abstract the routing table internals behind an rtable_* API.
Code abusing the radix internals for the routing table should now
includes <net/rtable.h> and only deal with "struct rtentry".
Code using a radix tree for another purpose can still include
<net/radix.h>.
Inputs from and ok claudio@, mikeb@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/net/if.c | 10 | ||||
-rw-r--r-- | sys/net/if_pppx.c | 4 | ||||
-rw-r--r-- | sys/net/if_spppsubr.c | 16 | ||||
-rw-r--r-- | sys/net/radix_mpath.c | 27 | ||||
-rw-r--r-- | sys/net/radix_mpath.h | 4 | ||||
-rw-r--r-- | sys/net/route.c | 248 | ||||
-rw-r--r-- | sys/net/route.h | 19 | ||||
-rw-r--r-- | sys/net/rtable.c | 204 | ||||
-rw-r--r-- | sys/net/rtable.h | 57 | ||||
-rw-r--r-- | sys/net/rtsock.c | 87 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 18 | ||||
-rw-r--r-- | sys/netinet/in_proto.c | 13 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 13 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 20 | ||||
-rw-r--r-- | sys/netmpls/mpls_proto.c | 7 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 6 |
17 files changed, 480 insertions, 276 deletions
diff --git a/sys/conf/files b/sys/conf/files index 0abdacef3f9..46676604e37 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.595 2015/07/17 22:52:29 tedu Exp $ +# $OpenBSD: files,v 1.596 2015/07/18 15:51:16 mpi Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -776,6 +776,7 @@ file net/radix.c file net/radix_mpath.c !small_kernel file net/raw_cb.c file net/raw_usrreq.c +file net/rtable.c file net/route.c file net/rtsock.c file net/slcompress.c ppp diff --git a/sys/net/if.c b/sys/net/if.c index d25a5400c40..d0e6c1373d1 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.350 2015/07/16 15:31:35 mpi Exp $ */ +/* $OpenBSD: if.c,v 1.351 2015/07/18 15:51:16 mpi Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -2093,7 +2093,8 @@ if_group_egress_build(void) bzero(&sa_in, sizeof(sa_in)); sa_in.sin_len = sizeof(sa_in); sa_in.sin_family = AF_INET; - if ((rt = rt_lookup(sintosa(&sa_in), sintosa(&sa_in), 0)) != NULL) { + rt = rtable_lookup(0, sintosa(&sa_in), sintosa(&sa_in)); + if (rt != NULL) { do { if (rt->rt_ifp) if_addgroup(rt->rt_ifp, IFG_EGRESS); @@ -2107,7 +2108,8 @@ if_group_egress_build(void) #ifdef INET6 bcopy(&sa6_any, &sa_in6, sizeof(sa_in6)); - if ((rt = rt_lookup(sin6tosa(&sa_in6), sin6tosa(&sa_in6), 0)) != NULL) { + rt = rtable_lookup(0, sin6tosa(&sa_in6), sin6tosa(&sa_in6)); + if (rt != NULL) { do { if (rt->rt_ifp) if_addgroup(rt->rt_ifp, IFG_EGRESS); @@ -2237,7 +2239,7 @@ ifa_print_all(void) } } } -#endif /* SMALL_KERNEL */ +#endif /* DDB */ void ifnewlladdr(struct ifnet *ifp) diff --git a/sys/net/if_pppx.c b/sys/net/if_pppx.c index 71692f03eac..525cd705485 100644 --- a/sys/net/if_pppx.c +++ b/sys/net/if_pppx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pppx.c,v 1.41 2015/07/15 22:16:42 deraadt Exp $ */ +/* $OpenBSD: if_pppx.c,v 1.42 2015/07/18 15:51:16 mpi Exp $ */ /* * Copyright (c) 2010 Claudio Jeker <claudio@openbsd.org> @@ -63,7 +63,6 @@ #include <net/if.h> #include <net/if_types.h> -#include <net/radix.h> #include <net/netisr.h> #include <netinet/in.h> #include <netinet/if_ether.h> @@ -89,6 +88,7 @@ #include <crypto/arc4.h> #ifdef PIPEX +#include <net/radix.h> #include <net/pipex.h> #include <net/pipex_local.h> #else diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index b6f94f95bf9..22bf11be23b 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_spppsubr.c,v 1.135 2015/06/30 13:54:42 mpi Exp $ */ +/* $OpenBSD: if_spppsubr.c,v 1.136 2015/07/18 15:51:16 mpi Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. * Keepalive protocol implemented in both Cisco and PPP modes. @@ -356,7 +356,7 @@ void sppp_phase_network(struct sppp *sp); void sppp_print_bytes(const u_char *p, u_short len); void sppp_print_string(const char *p, u_short len); void sppp_qflush(struct ifqueue *ifq); -int sppp_update_gw_walker(struct radix_node *rn, void *arg, u_int); +int sppp_update_gw_walker(struct rtentry *rt, void *arg, unsigned int id); void sppp_update_gw(struct ifnet *ifp); void sppp_set_ip_addrs(void *); void sppp_clear_ip_addrs(void *); @@ -4502,10 +4502,9 @@ sppp_get_ip_addrs(struct sppp *sp, u_int32_t *src, u_int32_t *dst, } int -sppp_update_gw_walker(struct radix_node *rn, void *arg, u_int id) +sppp_update_gw_walker(struct rtentry *rt, void *arg, unsigned int id) { struct ifnet *ifp = arg; - struct rtentry *rt = (struct rtentry *)rn; if (rt->rt_ifp == ifp) { if (rt->rt_ifa->ifa_dstaddr->sa_family != @@ -4521,16 +4520,13 @@ sppp_update_gw_walker(struct radix_node *rn, void *arg, u_int id) void sppp_update_gw(struct ifnet *ifp) { - struct radix_node_head *rnh; u_int tid; /* update routing table */ for (tid = 0; tid <= RT_TABLEID_MAX; tid++) { - if ((rnh = rtable_get(tid, AF_INET)) != NULL) { - while ((*rnh->rnh_walktree)(rnh, - sppp_update_gw_walker, ifp) == EAGAIN) - ; /* nothing */ - } + while (rtable_walk(tid, AF_INET, sppp_update_gw_walker, + ifp) == EAGAIN) + ; /* nothing */ } } diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c index e8921f5db17..c23d1ee70d9 100644 --- a/sys/net/radix_mpath.c +++ b/sys/net/radix_mpath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radix_mpath.c,v 1.30 2015/07/16 18:17:27 claudio Exp $ */ +/* $OpenBSD: radix_mpath.c,v 1.31 2015/07/18 15:51:16 mpi Exp $ */ /* $KAME: radix_mpath.c,v 1.13 2002/10/28 21:05:59 itojun Exp $ */ /* @@ -381,35 +381,16 @@ rn_mpath_reprio(struct radix_node *rn, int newprio) } } -/* - * allocate a route, potentially using multipath to select the peer. - */ +/* Gateway selection by Hash-Threshold (RFC 2992) */ struct rtentry * -rtalloc_mpath(struct sockaddr *dst, u_int32_t *srcaddrp, u_int rtableid) +rn_mpath_select(struct rtentry *rt, uint32_t *srcaddrp) { - struct rtentry *rt; struct radix_node *rn; int hash, npaths, threshold; - rt = rtalloc(dst, RT_REPORT|RT_RESOLVE, rtableid); - - /* if the route does not exist or it is not multipath, don't care */ - if (rt == NULL || !ISSET(rt->rt_flags, RTF_MPATH)) - return (rt); - - /* check if multipath routing is enabled for the specified protocol */ - if (!(0 - || (ipmultipath && dst->sa_family == AF_INET) -#ifdef INET6 - || (ip6_multipath && dst->sa_family == AF_INET6) -#endif - )) - return (rt); - - /* gw selection by Hash-Threshold (RFC 2992) */ rn = (struct radix_node *)rt; npaths = rn_mpath_active_count(rn); - hash = rn_mpath_hash(dst, srcaddrp) & 0xffff; + hash = rn_mpath_hash(rt_key(rt), srcaddrp) & 0xffff; threshold = 1 + (0xffff / npaths); while (hash > threshold && rn) { /* stay within the multipath routes */ diff --git a/sys/net/radix_mpath.h b/sys/net/radix_mpath.h index 5b3fe710973..a378a0d7020 100644 --- a/sys/net/radix_mpath.h +++ b/sys/net/radix_mpath.h @@ -1,4 +1,4 @@ -/* $OpenBSD: radix_mpath.h,v 1.15 2015/02/06 01:21:17 mpi Exp $ */ +/* $OpenBSD: radix_mpath.h,v 1.16 2015/07/18 15:51:16 mpi Exp $ */ /* $KAME: radix_mpath.h,v 1.9 2004/03/30 11:21:49 keiichi Exp $ */ /* @@ -54,9 +54,9 @@ void rn_mpath_adj_mpflag(struct radix_node *, u_int8_t); int rn_mpath_active_count(struct radix_node *); struct rtentry *rt_mpath_matchgate(struct rtentry *, struct sockaddr *, u_int8_t); +struct rtentry *rn_mpath_select(struct rtentry *, uint32_t *); int rt_mpath_conflict(struct radix_node_head *, struct sockaddr *, struct sockaddr *, struct sockaddr *, u_int8_t, int); -struct rtentry *rtalloc_mpath(struct sockaddr *, u_int32_t *, u_int); int rn_mpath_inithead(void **, int); #endif /* _KERNEL */ diff --git a/sys/net/route.c b/sys/net/route.c index 738b49cb8fb..f2b1be29513 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.216 2015/07/16 18:17:27 claudio Exp $ */ +/* $OpenBSD: route.c,v 1.217 2015/07/18 15:51:16 mpi Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -120,6 +120,12 @@ #include <net/route.h> #include <netinet/in.h> +#include <netinet/ip_var.h> + +#ifdef INET6 +#include <netinet/ip6.h> +#include <netinet6/ip6_var.h> +#endif #ifdef MPLS #include <netmpls/mpls.h> @@ -131,7 +137,7 @@ #endif struct rtstat rtstat; -struct radix_node_head ***rt_tables; +void ***rt_tables; u_int8_t af2rtafidx[AF_MAX+1]; u_int8_t rtafidx_max; u_int rtbl_id_max = 0; @@ -143,10 +149,10 @@ struct pool rtentry_pool; /* pool for rtentry structures */ struct pool rttimer_pool; /* pool for rttimer structures */ void rt_timer_init(void); -int rtable_init(struct radix_node_head ***, u_int); -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 *, u_int); +int rtable_alloc(void ***, u_int); +int rtflushclone1(struct rtentry *, void *, u_int); +void rtflushclone(unsigned int, struct rtentry *); +int rt_if_remove_rtdelete(struct rtentry *, void *, u_int); struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *, u_int); @@ -163,7 +169,7 @@ struct rt_label { TAILQ_HEAD(rt_labels, rt_label) rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels); int -rtable_init(struct radix_node_head ***table, u_int id) +rtable_alloc(void ***table, u_int id) { void **p; struct domain *dom; @@ -179,12 +185,10 @@ rtable_init(struct radix_node_head ***table, u_int id) dom->dom_rtattach(&p[af2rtafidx[dom->dom_family]], dom->dom_rtoffset); - *table = (struct radix_node_head **)p; + for (i = 0; i < rtafidx_max; i++) + rtable_setid(p, id, i); - for (i = 0; i < rtafidx_max; i++) { - if ((*table)[i] != NULL) - (*table)[i]->rnh_rtableid = id; - } + *table = (void **)p; return (0); } @@ -196,7 +200,7 @@ route_init(void) pool_init(&rtentry_pool, sizeof(struct rtentry), 0, 0, 0, "rtentry", NULL); - rn_init(); /* initialize all zeroes, all ones, mask table */ + rtable_init(); /* initialize all zeroes, all ones, mask table */ bzero(af2rtafidx, sizeof(af2rtafidx)); rtafidx_max = 1; /* must have NULL at index 0, so start at 1 */ @@ -249,10 +253,10 @@ rtable_add(u_int id) return (EEXIST); rt_tab2dom[id] = 0; /* use main table/domain by default */ - return (rtable_init(&rt_tables[id], id)); + return (rtable_alloc(&rt_tables[id], id)); } -struct radix_node_head * +void * rtable_get(u_int id, sa_family_t af) { if (id > rtbl_id_max) @@ -296,9 +300,7 @@ rtable_exists(u_int id) /* verify table with that ID exists */ struct rtentry * rtalloc(struct sockaddr *dst, int flags, unsigned int tableid) { - struct radix_node_head *rnh; struct rtentry *rt; - struct radix_node *rn; struct rtentry *newrt = 0; struct rt_addrinfo info; int s = splsoftnet(), err = 0, msgtype = RTM_MISS; @@ -306,9 +308,9 @@ rtalloc(struct sockaddr *dst, int flags, unsigned int tableid) bzero(&info, sizeof(info)); info.rti_info[RTAX_DST] = dst; - rnh = rtable_get(tableid, dst->sa_family); - if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh))) { - newrt = rt = (struct rtentry *)rn; + rt = rtable_match(tableid, dst); + if (rt != NULL) { + newrt = rt; if ((rt->rt_flags & RTF_CLONING) && ISSET(flags, RT_RESOLVE)) { err = rtrequest1(RTM_RESOLVE, &info, RTP_DEFAULT, &newrt, tableid); @@ -344,6 +346,34 @@ miss: return (newrt); } +#ifndef SMALL_KERNEL +/* + * Allocate a route, potentially using multipath to select the peer. + */ +struct rtentry * +rtalloc_mpath(struct sockaddr *dst, uint32_t *src, unsigned int rtableid) +{ + struct rtentry *rt; + + rt = rtalloc(dst, RT_REPORT|RT_RESOLVE, rtableid); + + /* if the route does not exist or it is not multipath, don't care */ + if (rt == NULL || !ISSET(rt->rt_flags, RTF_MPATH)) + return (rt); + + /* check if multipath routing is enabled for the specified protocol */ + if (!(0 + || (ipmultipath && dst->sa_family == AF_INET) +#ifdef INET6 + || (ip6_multipath && dst->sa_family == AF_INET6) +#endif + )) + return (rt); + + return (rtable_mpath_select(rt, src)); +} +#endif /* SMALL_KERNEL */ + void rtfree(struct rtentry *rt) { @@ -354,9 +384,9 @@ rtfree(struct rtentry *rt) rt->rt_refcnt--; if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) { - if (rt->rt_refcnt == 0 && (rt->rt_nodes->rn_flags & RNF_ACTIVE)) + if (rt->rt_refcnt == 0 && RT_ACTIVE(rt)) return; /* route still active but currently down */ - if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) + if (RT_ACTIVE(rt) || RT_ROOT(rt)) panic("rtfree 2"); rttrash--; if (rt->rt_refcnt < 0) { @@ -564,12 +594,10 @@ rtequal(struct rtentry *a, struct rtentry *b) } int -rtflushclone1(struct radix_node *rn, void *arg, u_int id) +rtflushclone1(struct rtentry *rt, void *arg, u_int id) { - struct rtentry *rt, *parent; + struct rtentry *parent = arg; - rt = (struct rtentry *)rn; - parent = (struct rtentry *)arg; if ((rt->rt_flags & RTF_CLONED) != 0 && (rt->rt_parent == parent || rtequal(rt->rt_parent, parent))) rtdeletemsg(rt, id); @@ -577,16 +605,14 @@ rtflushclone1(struct radix_node *rn, void *arg, u_int id) } void -rtflushclone(struct radix_node_head *rnh, struct rtentry *parent) +rtflushclone(unsigned int rtableid, struct rtentry *parent) { #ifdef DIAGNOSTIC if (!parent || (parent->rt_flags & RTF_CLONING) == 0) panic("rtflushclone: called with a non-cloning route"); - if (!rnh->rnh_walktree) - panic("rtflushclone: no rnh_walktree"); #endif - rnh->rnh_walktree(rnh, rtflushclone1, (void *)parent); + rtable_walk(rtableid, rt_key(parent)->sa_family, rtflushclone1, parent); } int @@ -723,8 +749,6 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, struct rtentry **ret_nrt, u_int tableid) { struct rtentry *rt, *crt; - struct radix_node *rn; - struct radix_node_head *rnh; struct ifaddr *ifa; struct sockaddr *ndst; struct sockaddr_rtlabel *sa_rl, sa_rl2; @@ -736,31 +760,29 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, splsoftassert(IPL_SOFTNET); - if ((rnh = rtable_get(tableid, info->rti_info[RTAX_DST]->sa_family)) == - NULL) + if (!rtable_exists(tableid)) return (EAFNOSUPPORT); if (info->rti_flags & RTF_HOST) info->rti_info[RTAX_NETMASK] = NULL; switch (req) { case RTM_DELETE: - if ((rn = rnh->rnh_lookup(info->rti_info[RTAX_DST], - info->rti_info[RTAX_NETMASK], rnh)) == NULL) + rt = rtable_lookup(tableid, info->rti_info[RTAX_DST], + info->rti_info[RTAX_NETMASK]); + if (rt == NULL) return (ESRCH); - rt = (struct rtentry *)rn; #ifndef SMALL_KERNEL + rt = rtable_mpath_match(tableid, rt, + info->rti_info[RTAX_GATEWAY], prio); + if (rt == NULL) + return (ESRCH); + /* - * if we got multipath routes, we require users to specify - * a matching RTAX_GATEWAY. + * If we got multipath routes, we require users to specify + * a matching gateway. */ - if (rn_mpath_capable(rnh)) { - rt = rt_mpath_matchgate(rt, - info->rti_info[RTAX_GATEWAY], prio); - rn = (struct radix_node *)rt; - if (!rt || - (!info->rti_info[RTAX_GATEWAY] && - rt->rt_flags & RTF_MPATH)) - return (ESRCH); - } + if ((rt->rt_flags & RTF_MPATH) && + info->rti_info[RTAX_GATEWAY] == NULL) + return (ESRCH); #endif /* @@ -772,17 +794,14 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, prio != RTP_LOCAL) return (EINVAL); - if ((rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST], - info->rti_info[RTAX_NETMASK], rnh, rn)) == NULL) + error = rtable_delete(tableid, info->rti_info[RTAX_DST], + info->rti_info[RTAX_NETMASK], prio, rt); + if (error != 0) return (ESRCH); - rt = (struct rtentry *)rn; /* clean up any cloned children */ if ((rt->rt_flags & RTF_CLONING) != 0) - rtflushclone(rnh, rt); - - if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) - panic ("rtrequest delete"); + rtflushclone(tableid, rt); if (rt->rt_gwroute) { rtfree(rt->rt_gwroute); @@ -855,15 +874,12 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, memcpy(ndst, info->rti_info[RTAX_DST], dlen); #ifndef SMALL_KERNEL - if (rn_mpath_capable(rnh)) { - /* do not permit exactly the same dst/mask/gw pair */ - if (rt_mpath_conflict(rnh, ndst, - info->rti_info[RTAX_NETMASK], - info->rti_info[RTAX_GATEWAY], prio, - info->rti_flags & RTF_MPATH)) { - free(ndst, M_RTABLE, dlen); - return (EEXIST); - } + /* Do not permit exactly the same dst/mask/gw pair. */ + if (rtable_mpath_conflict(tableid, ndst, + info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY], + prio, info->rti_flags & RTF_MPATH)) { + free(ndst, M_RTABLE, dlen); + return (EEXIST); } #endif rt = pool_get(&rtentry_pool, PR_NOWAIT | PR_ZERO); @@ -878,7 +894,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, LIST_INIT(&rt->rt_timer); #ifndef SMALL_KERNEL - if (rn_mpath_capable(rnh)) { + if (rtable_mpath_capable(tableid, ndst->sa_family)) { /* check the link state since the table supports it */ if (LINK_STATE_IS_UP(ifa->ifa_ifp->if_link_state) && ifa->ifa_ifp->if_flags & IFF_UP) @@ -974,20 +990,19 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, return (error); } - rn = rnh->rnh_addaddr((caddr_t)ndst, - (caddr_t)info->rti_info[RTAX_NETMASK], rnh, rt->rt_nodes, - rt->rt_priority); - if (rn == NULL && (crt = rtalloc(ndst, 0, tableid)) != NULL) { + error = rtable_insert(tableid, ndst, + info->rti_info[RTAX_NETMASK], rt->rt_priority, rt); + if (error != 0 && (crt = rtalloc(ndst, 0, tableid)) != NULL) { /* overwrite cloned route */ if ((crt->rt_flags & RTF_CLONED) != 0) { rtdeletemsg(crt, tableid); - rn = rnh->rnh_addaddr((caddr_t)ndst, - (caddr_t)info->rti_info[RTAX_NETMASK], - rnh, rt->rt_nodes, rt->rt_priority); - } + error = rtable_insert(tableid, ndst, + info->rti_info[RTAX_NETMASK], + rt->rt_priority, rt); + } rtfree(crt); } - if (rn == 0) { + if (error != 0) { ifafree(ifa); if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent) rtfree(rt->rt_parent); @@ -1008,7 +1023,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, } if ((rt->rt_flags & RTF_CLONING) != 0) { /* clean up any cloned children */ - rtflushclone(rnh, rt); + rtflushclone(tableid, rt); } if_group_routechange(info->rti_info[RTAX_DST], @@ -1517,17 +1532,6 @@ rt_timer_add(struct rtentry *rt, void (*func)(struct rtentry *, return (0); } -struct rtentry * -rt_lookup(struct sockaddr *dst, struct sockaddr *mask, u_int tableid) -{ - struct radix_node_head *rnh; - - if ((rnh = rtable_get(tableid, dst->sa_family)) == NULL) - return (NULL); - - return ((struct rtentry *)rnh->rnh_lookup(dst, mask, rnh)); -} - /* ARGSUSED */ void rt_timer_timer(void *arg) @@ -1657,16 +1661,14 @@ rt_if_remove(struct ifnet *ifp) { int i; u_int tid; - struct radix_node_head *rnh; for (tid = 0; tid <= rtbl_id_max; tid++) { /* skip rtables that are not in the rdomain of the ifp */ if (rtable_l2(tid) != ifp->if_rdomain) continue; for (i = 1; i <= AF_MAX; i++) { - if ((rnh = rtable_get(tid, i)) != NULL) - while ((*rnh->rnh_walktree)(rnh, - rt_if_remove_rtdelete, ifp) == EAGAIN) + while (rtable_walk(tid, i, rt_if_remove_rtdelete, + ifp) == EAGAIN) ; /* nothing */ } } @@ -1679,10 +1681,9 @@ rt_if_remove(struct ifnet *ifp) * as long as EAGAIN is returned. */ int -rt_if_remove_rtdelete(struct radix_node *rn, void *vifp, u_int id) +rt_if_remove_rtdelete(struct rtentry *rt, void *vifp, u_int id) { struct ifnet *ifp = vifp; - struct rtentry *rt = (struct rtentry *)rn; if (rt->rt_ifp == ifp) { int cloning = (rt->rt_flags & RTF_CLONING); @@ -1703,7 +1704,6 @@ rt_if_remove_rtdelete(struct radix_node *rn, void *vifp, u_int id) void rt_if_track(struct ifnet *ifp) { - struct radix_node_head *rnh; int i; u_int tid; @@ -1715,49 +1715,47 @@ rt_if_track(struct ifnet *ifp) if (rtable_l2(tid) != ifp->if_rdomain) continue; for (i = 1; i <= AF_MAX; i++) { - if ((rnh = rtable_get(tid, i)) != NULL) { - if (!rn_mpath_capable(rnh)) - continue; - while ((*rnh->rnh_walktree)(rnh, - rt_if_linkstate_change, ifp) == EAGAIN) - ; /* nothing */ - } + if (!rtable_mpath_capable(tid, i)) + continue; + + while (rtable_walk(tid, i, + rt_if_linkstate_change, ifp) == EAGAIN) + ; /* nothing */ } } } int -rt_if_linkstate_change(struct radix_node *rn, void *arg, u_int id) +rt_if_linkstate_change(struct rtentry *rt, void *arg, u_int id) { struct ifnet *ifp = arg; - struct rtentry *rt = (struct rtentry *)rn; - if (rt->rt_ifp == ifp) { - if (LINK_STATE_IS_UP(ifp->if_link_state) && - ifp->if_flags & IFF_UP) { - if (!(rt->rt_flags & RTF_UP)) { - /* bring route up */ - rt->rt_flags |= RTF_UP; - rn_mpath_reprio(rn, rt->rt_priority & RTP_MASK); - } - } else { - if (rt->rt_flags & RTF_UP) { - /* - * Remove cloned routes (mainly arp) to - * down interfaces so we have a chance to - * clone a new route from a better source. - */ - if (rt->rt_flags & RTF_CLONED) { - rtdeletemsg(rt, id); - return (0); - } - /* take route down */ - rt->rt_flags &= ~RTF_UP; - rn_mpath_reprio(rn, rt->rt_priority | RTP_DOWN); + if (rt->rt_ifp != ifp) + return (0); + + if (LINK_STATE_IS_UP(ifp->if_link_state) && ifp->if_flags & IFF_UP) { + if (!(rt->rt_flags & RTF_UP)) { + /* bring route up */ + rt->rt_flags |= RTF_UP; + rtable_mpath_reprio(rt, rt->rt_priority & RTP_MASK); + } + } else { + if (rt->rt_flags & RTF_UP) { + /* + * Remove cloned routes (mainly arp) to + * down interfaces so we have a chance to + * clone a new route from a better source. + */ + if (rt->rt_flags & RTF_CLONED) { + rtdeletemsg(rt, id); + return (0); } + /* take route down */ + rt->rt_flags &= ~RTF_UP; + rtable_mpath_reprio(rt, rt->rt_priority | RTP_DOWN); } - if_group_routechange(rt_key(rt), rt_mask(rt)); } + if_group_routechange(rt_key(rt), rt_mask(rt)); return (0); } diff --git a/sys/net/route.h b/sys/net/route.h index 3f6a938653f..40bf7b6a6ad 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.108 2015/07/08 07:56:51 mpi Exp $ */ +/* $OpenBSD: route.h,v 1.109 2015/07/18 15:51:16 mpi Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -80,9 +80,8 @@ struct rt_metrics { #define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */ #define RTTTOPRHZ(r) ((r) / (RTM_RTTUNIT / PR_SLOWHZ)) -#ifdef _KERNEL - #include <sys/queue.h> +#include <net/rtable.h> /* * We distinguish between routes to hosts and routes to networks, @@ -92,13 +91,9 @@ struct rt_metrics { * gateways are marked so that the output routines know to address the * gateway rather than the ultimate destination. */ -#include <net/radix.h> -#include <net/radix_mpath.h> struct rtentry { struct radix_node rt_nodes[2]; /* tree glue, and other values */ -#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key)) -#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask)) struct sockaddr *rt_gateway; /* value */ struct ifnet *rt_ifp; /* the answer: interface to use */ struct ifaddr *rt_ifa; /* the answer: interface addr to use */ @@ -117,8 +112,6 @@ struct rtentry { #define rt_use rt_rmx.rmx_pksent #define rt_expire rt_rmx.rmx_expire -#endif /* _KERNEL */ - #define RTF_UP 0x1 /* route usable */ #define RTF_GATEWAY 0x2 /* destination is a gateway */ #define RTF_HOST 0x4 /* host entry (net otherwise) */ @@ -342,10 +335,10 @@ void rtlabel_unref(u_int16_t); extern struct rtstat rtstat; extern const struct sockaddr_rtin rt_defmask4; +struct mbuf; struct socket; void route_init(void); int rtable_add(u_int); -struct radix_node_head *rtable_get(u_int, sa_family_t); u_int rtable_l2(u_int); void rtable_l2set(u_int, u_int); int rtable_exists(u_int); @@ -379,6 +372,8 @@ void rt_timer_timer(void *); #ifdef SMALL_KERNEL #define rtalloc_mpath(dst, s, rid) rtalloc((dst), RT_REPORT|RT_RESOLVE, (rid)) +#else +struct rtentry *rtalloc_mpath(struct sockaddr *, uint32_t *, u_int); #endif struct rtentry *rtalloc(struct sockaddr *, int, unsigned int); void rtfree(struct rtentry *); @@ -397,12 +392,10 @@ 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 *, u_int); +int rt_if_linkstate_change(struct rtentry *, void *, u_int); #endif int rtdeletemsg(struct rtentry *, u_int); -struct rtentry *rt_lookup(struct sockaddr *, struct sockaddr *, u_int); - struct rtentry *rt_mpath_next(struct rtentry *); #endif /* _KERNEL */ diff --git a/sys/net/rtable.c b/sys/net/rtable.c new file mode 100644 index 00000000000..48206248094 --- /dev/null +++ b/sys/net/rtable.c @@ -0,0 +1,204 @@ +/* $OpenBSD: rtable.c,v 1.1 2015/07/18 15:51:16 mpi Exp $ */ + +/* + * Copyright (c) 2014-2015 Martin Pieuchot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/socket.h> + +#include <net/rtable.h> +#include <net/route.h> + +void +rtable_init(void) +{ + rn_init(); +} + +int +rtable_attach(void **head, int off) +{ + int rv; + +#ifndef SMALL_KERNEL + rv = rn_mpath_inithead(head, off); +#else + rv = rn_inithead(head, off); +#endif + + return (rv); +} + +struct rtentry * +rtable_lookup(unsigned int rtableid, struct sockaddr *dst, + struct sockaddr *mask) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + + rnh = rtable_get(rtableid, dst->sa_family); + if (rnh == NULL) + return (NULL); + + rn = rnh->rnh_lookup(dst, mask, rnh); + if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) + return (NULL); + + return ((struct rtentry *)rn); +} + +struct rtentry * +rtable_match(unsigned int rtableid, struct sockaddr *dst) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + + rnh = rtable_get(rtableid, dst->sa_family); + if (rnh == NULL) + return (NULL); + + rn = rnh->rnh_matchaddr(dst, rnh); + if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) + return (NULL); + + return ((struct rtentry *)rn); +} + +int +rtable_insert(unsigned int rtableid, struct sockaddr *dst, + struct sockaddr *mask, uint8_t prio, struct rtentry *rt) +{ + struct radix_node_head *rnh; + struct radix_node *rn = (struct radix_node *)rt; + + rnh = rtable_get(rtableid, dst->sa_family); + if (rnh == NULL) + return (EAFNOSUPPORT); + + rn = rnh->rnh_addaddr(dst, mask, rnh, rn, prio); + if (rn == NULL) + return (ESRCH); + + return (0); +} + +int +rtable_delete(unsigned int rtableid, struct sockaddr *dst, + struct sockaddr *mask, uint8_t prio, struct rtentry *rt) +{ + struct radix_node_head *rnh; + struct radix_node *rn = (struct radix_node *)rt; + + rnh = rtable_get(rtableid, dst->sa_family); + if (rnh == NULL) + return (EAFNOSUPPORT); + + rn = rnh->rnh_deladdr(dst, mask, rnh, rn); + if (rn == NULL) + return (ESRCH); + + if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) + panic("active node flags=%x", rn->rn_flags); + + return (0); +} + +int +rtable_setid(void **p, unsigned int rtableid, sa_family_t af) +{ + struct radix_node_head **rnh = (struct radix_node_head **)p; + + if (rnh == NULL || rnh[af] == NULL) + return (EINVAL); + + rnh[af]->rnh_rtableid = rtableid; + + return (0); +} + +int +rtable_walk(unsigned int rtableid, sa_family_t af, + int (*func)(struct rtentry *, void *, unsigned int), void *arg) +{ + struct radix_node_head *rnh; + int (*f)(struct radix_node *, void *, u_int) = (void *)func; + + rnh = rtable_get(rtableid, af); + if (rnh == NULL) + return (EAFNOSUPPORT); + + return (*rnh->rnh_walktree)(rnh, f, arg); +} + +#ifndef SMALL_KERNEL +int +rtable_mpath_capable(unsigned int rtableid, sa_family_t af) +{ + struct radix_node_head *rnh; + + rnh = rtable_get(rtableid, af); + if (rnh == NULL) + return (0); + + return (rnh->rnh_multipath); +} + +struct rtentry * +rtable_mpath_match(unsigned int rtableid, struct rtentry *rt, + struct sockaddr *gateway, uint8_t prio) +{ + struct radix_node_head *rnh; + + rnh = rtable_get(rtableid, rt_key(rt)->sa_family); + if (rnh == NULL || rnh->rnh_multipath == 0) + return (rt); + + rt = rt_mpath_matchgate(rt, gateway, prio); + + return (rt); +} + +int +rtable_mpath_conflict(unsigned int rtableid, struct sockaddr *dst, + struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, int mpathok) +{ + struct radix_node_head *rnh; + + rnh = rtable_get(rtableid, dst->sa_family); + if (rnh == NULL) + return (EAFNOSUPPORT); + + if (rnh->rnh_multipath == 0) + return (0); + + return (rt_mpath_conflict(rnh, dst, mask, gateway, prio, mpathok)); +} + +struct rtentry * +rtable_mpath_select(struct rtentry *rt, uint32_t *src) +{ + return (rn_mpath_select(rt, src)); +} + +void +rtable_mpath_reprio(struct rtentry *rt, uint8_t newprio) +{ + struct radix_node *rn = (struct radix_node *)rt; + + rn_mpath_reprio(rn, newprio); +} +#endif diff --git a/sys/net/rtable.h b/sys/net/rtable.h new file mode 100644 index 00000000000..9a6a9c74b66 --- /dev/null +++ b/sys/net/rtable.h @@ -0,0 +1,57 @@ +/* $OpenBSD: rtable.h,v 1.1 2015/07/18 15:51:16 mpi Exp $ */ + +/* + * Copyright (c) 2014-2015 Martin Pieuchot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _NET_RTABLE_H_ +#define _NET_RTABLE_H_ + +/* + * Traditional BSD routing table implementation based on a radix tree. + */ +#include <net/radix.h> +#ifndef SMALL_KERNEL +#include <net/radix_mpath.h> +#endif + +#define rt_key(rt) (((struct sockaddr *)(rt)->rt_nodes[0].rn_key)) +#define rt_mask(rt) (((struct sockaddr *)(rt)->rt_nodes[0].rn_mask)) +#define RT_ACTIVE(rt) ((rt)->rt_nodes[0].rn_flags & RNF_ACTIVE) +#define RT_ROOT(rt) ((rt)->rt_nodes[0].rn_flags & RNF_ROOT) + +void rtable_init(void); +int rtable_attach(void **, int); +struct rtentry *rtable_lookup(unsigned int, struct sockaddr *, + struct sockaddr *); +struct rtentry *rtable_match(unsigned int, struct sockaddr *); +int rtable_insert(unsigned int, struct sockaddr *, + struct sockaddr *, uint8_t, struct rtentry *); +int rtable_delete(unsigned int, struct sockaddr *, + struct sockaddr *, uint8_t, struct rtentry *); + +int rtable_setid(void **, unsigned int, sa_family_t); +void *rtable_get(unsigned int, sa_family_t); +int rtable_walk(unsigned int, sa_family_t, + int (*)(struct rtentry *, void *, unsigned int), void *); + +int rtable_mpath_capable(unsigned int, sa_family_t); +struct rtentry *rtable_mpath_match(unsigned int, struct rtentry *, + struct sockaddr *, uint8_t); +int rtable_mpath_conflict(unsigned int, struct sockaddr *, + struct sockaddr *, struct sockaddr *, uint8_t, int); +struct rtentry *rtable_mpath_select(struct rtentry *, uint32_t *); +void rtable_mpath_reprio(struct rtentry *, uint8_t); +#endif /* _NET_RTABLE_H_ */ diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index a8684186a94..88826887e4d 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.164 2015/07/18 00:02:30 phessler Exp $ */ +/* $OpenBSD: rtsock.c,v 1.165 2015/07/18 15:51:16 mpi Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -445,7 +445,6 @@ route_output(struct mbuf *m, ...) struct rt_msghdr *rtm = NULL; struct rtentry *rt = NULL; struct rtentry *saved_nrt = NULL; - struct radix_node_head *rnh; struct rt_addrinfo info; int len, newgate, error = 0; struct ifnet *ifp = NULL; @@ -617,52 +616,51 @@ route_output(struct mbuf *m, ...) case RTM_GET: case RTM_CHANGE: case RTM_LOCK: - rnh = rtable_get(tableid, info.rti_info[RTAX_DST]->sa_family); - if (rnh == NULL) { + if (!rtable_exists(tableid)) { error = EAFNOSUPPORT; goto flush; } - rt = rt_lookup(info.rti_info[RTAX_DST], - info.rti_info[RTAX_NETMASK], tableid); + rt = rtable_lookup(tableid, info.rti_info[RTAX_DST], + info.rti_info[RTAX_NETMASK]); if (rt == NULL) { error = ESRCH; goto flush; } #ifndef SMALL_KERNEL - if (rn_mpath_capable(rnh)) { - /* first find the right priority */ - rt = rt_mpath_matchgate(rt, NULL, prio); - if (!rt) { + /* First find the right priority. */ + rt = rtable_mpath_match(tableid, rt, NULL, prio); + if (rt == NULL) { + error = ESRCH; + goto flush; + } + + + /* + * For RTM_CHANGE/LOCK, if we got multipath routes, + * a matching RTAX_GATEWAY is required. + * OR + * If a gateway is specified then RTM_GET and + * RTM_LOCK must match the gateway no matter + * what even in the non multipath case. + */ + if ((rt->rt_flags & RTF_MPATH) || + (info.rti_info[RTAX_GATEWAY] && rtm->rtm_type != + RTM_CHANGE)) { + rt = rtable_mpath_match(tableid, rt, + info.rti_info[RTAX_GATEWAY], prio); + if (rt == NULL) { error = ESRCH; goto flush; } /* - * For RTM_CHANGE/LOCK, if we got multipath routes, - * a matching RTAX_GATEWAY is required. - * OR - * If a gateway is specified then RTM_GET and - * RTM_LOCK must match the gateway no matter - * what even in the non multipath case. + * Only RTM_GET may use an empty gateway + * on multipath routes */ - if ((rt->rt_flags & RTF_MPATH) || - (info.rti_info[RTAX_GATEWAY] && rtm->rtm_type != - RTM_CHANGE)) { - rt = rt_mpath_matchgate(rt, - info.rti_info[RTAX_GATEWAY], prio); - if (!rt) { - error = ESRCH; - goto flush; - } - /* - * only RTM_GET may use an empty gateway - * on multipath routes - */ - if (!info.rti_info[RTAX_GATEWAY] && - rtm->rtm_type != RTM_GET) { - rt = NULL; - error = ESRCH; - goto flush; - } + if (info.rti_info[RTAX_GATEWAY] == NULL && + rtm->rtm_type != RTM_GET) { + rt = NULL; + error = ESRCH; + goto flush; } } #endif @@ -776,8 +774,7 @@ report: rt->rt_ifp = ifa->ifa_ifp; #ifndef SMALL_KERNEL /* recheck link state after ifp change*/ - rt_if_linkstate_change( - (struct radix_node *)rt, rt->rt_ifp, + rt_if_linkstate_change(rt, rt->rt_ifp, tableid); #endif } @@ -1197,10 +1194,9 @@ 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, u_int id) +sysctl_dumpentry(struct rtentry *rt, void *v, unsigned int id) { struct walkarg *w = v; - struct rtentry *rt = (struct rtentry *)rn; int error = 0, size; struct rt_addrinfo info; #ifdef MPLS @@ -1332,7 +1328,6 @@ int sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, size_t newlen) { - struct radix_node_head *rnh; int i, s, error = EINVAL; u_char af; struct walkarg w; @@ -1363,12 +1358,14 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, case NET_RT_DUMP: case NET_RT_FLAGS: - for (i = 1; i <= AF_MAX; i++) - if ((rnh = rtable_get(tableid, i)) != NULL && - (af == 0 || af == i) && - (error = (*rnh->rnh_walktree)(rnh, - sysctl_dumpentry, &w))) + for (i = 1; i <= AF_MAX; i++) { + if (af != 0 && af != i) + continue; + + error = rtable_walk(tableid, i, sysctl_dumpentry, &w); + if (error) break; + } break; case NET_RT_IFLIST: diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 8fbf0bdc77a..4b9d5452357 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.158 2015/07/17 18:35:25 mpi Exp $ */ +/* $OpenBSD: if_ether.c,v 1.159 2015/07/18 15:51:16 mpi Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -118,7 +118,7 @@ struct ifnet *revarp_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 *, u_int); +int db_show_rtentry(struct rtentry *, void *, unsigned int); #endif /* @@ -1077,14 +1077,12 @@ db_print_llinfo(caddr_t li) } /* - * Function to pass to rn_walktree(). + * Function to pass to rtalble_walk(). * Return non-zero error to abort walk. */ int -db_show_radix_node(struct radix_node *rn, void *w, u_int id) +db_show_rtentry(struct rtentry *rt, void *w, unsigned int id) { - struct rtentry *rt = (struct rtentry *)rn; - db_printf("rtentry=%p", rt); db_printf(" flags=0x%x refcnt=%d use=%llu expire=%lld rtableid=%u\n", @@ -1115,14 +1113,8 @@ db_show_radix_node(struct radix_node *rn, void *w, u_int id) int db_show_arptab(void) { - struct radix_node_head *rnh; - rnh = rtable_get(0, AF_INET); db_printf("Route tree for AF_INET\n"); - if (rnh == NULL) { - db_printf(" (not initialized)\n"); - return (0); - } - rn_walktree(rnh, db_show_radix_node, NULL); + rtable_walk(0, AF_INET, db_show_rtentry, NULL); return (0); } #endif diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index d11a3f84a29..1e074a11ab6 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_proto.c,v 1.63 2014/12/05 15:50:04 mpi Exp $ */ +/* $OpenBSD: in_proto.c,v 1.64 2015/07/18 15:51:17 mpi Exp $ */ /* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */ /* @@ -106,10 +106,7 @@ #include <net/if.h> #include <net/if_var.h> #include <net/route.h> -#include <net/radix.h> -#ifndef SMALL_KERNEL -#include <net/radix_mpath.h> -#endif +#include <net/rtable.h> #include <netinet/in.h> #include <netinet/ip.h> @@ -313,9 +310,5 @@ struct protosw inetsw[] = { struct domain inetdomain = { AF_INET, "internet", 0, 0, 0, inetsw, &inetsw[nitems(inetsw)], 0, -#ifndef SMALL_KERNEL - rn_mpath_inithead, -#else - rn_inithead, -#endif + rtable_attach, 32, sizeof(struct sockaddr_in) }; diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index c16da207152..de32544d985 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_proto.c,v 1.77 2014/12/19 17:14:40 tedu Exp $ */ +/* $OpenBSD: in6_proto.c,v 1.78 2015/07/18 15:51:17 mpi Exp $ */ /* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */ /* @@ -70,11 +70,8 @@ #include <net/if.h> #include <net/if_var.h> -#include <net/radix.h> -#ifndef SMALL_KERNEL -#include <net/radix_mpath.h> -#endif #include <net/route.h> +#include <net/rtable.h> #include <netinet/in.h> #include <netinet/ip.h> @@ -249,11 +246,7 @@ struct domain inet6domain = { AF_INET6, "internet6", 0, 0, 0, (struct protosw *)inet6sw, (struct protosw *)&inet6sw[nitems(inet6sw)], 0, -#ifndef SMALL_KERNEL - rn_mpath_inithead, -#else - rn_inithead, -#endif + rtable_attach, offsetof(struct sockaddr_in6, sin6_addr) << 3, sizeof(struct sockaddr_in6), in6_domifattach, in6_domifdetach, }; diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 6a1255538d8..fa2ab04e923 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.112 2015/07/18 15:05:32 mpi Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.113 2015/07/18 15:51:17 mpi Exp $ */ /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* @@ -49,7 +49,7 @@ #include <net/if_var.h> #include <net/if_types.h> #include <net/route.h> -#include <net/radix.h> +#include <net/rtable.h> #include <netinet/in.h> #include <netinet6/in6_var.h> @@ -72,7 +72,7 @@ void purge_detached(struct ifnet *); void in6_init_address_ltimes(struct nd_prefix *, struct in6_addrlifetime *); -int rt6_deleteroute(struct radix_node *, void *, u_int); +int rt6_deleteroute(struct rtentry *, void *, unsigned int); void nd6_addr_add(void *); @@ -2184,26 +2184,24 @@ in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6) void rt6_flush(struct in6_addr *gateway, struct ifnet *ifp) { - struct radix_node_head *rnh = rtable_get(ifp->if_rdomain, AF_INET6); - int s = splsoftnet(); + int s; /* We'll care only link-local addresses */ - if (!IN6_IS_ADDR_LINKLOCAL(gateway)) { - splx(s); + if (!IN6_IS_ADDR_LINKLOCAL(gateway)) return; - } + /* XXX: hack for KAME's link-local address kludge */ gateway->s6_addr16[1] = htons(ifp->if_index); - rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway); + s = splsoftnet(); + rtable_walk(ifp->if_rdomain, AF_INET6, rt6_deleteroute, gateway); splx(s); } int -rt6_deleteroute(struct radix_node *rn, void *arg, u_int id) +rt6_deleteroute(struct rtentry *rt, void *arg, unsigned int id) { struct rt_addrinfo info; - struct rtentry *rt = (struct rtentry *)rn; struct in6_addr *gate = (struct in6_addr *)arg; if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) diff --git a/sys/netmpls/mpls_proto.c b/sys/netmpls/mpls_proto.c index 0354abce9d6..d81f98a337c 100644 --- a/sys/netmpls/mpls_proto.c +++ b/sys/netmpls/mpls_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_proto.c,v 1.9 2014/12/05 15:50:04 mpi Exp $ */ +/* $OpenBSD: mpls_proto.c,v 1.10 2015/07/18 15:51:17 mpi Exp $ */ /* * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. @@ -38,8 +38,7 @@ #include <net/if.h> #include <net/if_var.h> -#include <net/radix.h> -#include <net/radix_mpath.h> +#include <net/rtable.h> #include <netmpls/mpls.h> @@ -69,7 +68,7 @@ struct domain mplsdomain = { AF_MPLS, "mpls", mpls_init, 0, 0, mplssw, &mplssw[nitems(mplssw)], 0, - rn_mpath_inithead, + rtable_attach, offsetof(struct sockaddr_mpls, smpls_label) << 3, sizeof(struct sockaddr_mpls) }; diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 425dfc51b62..33e0222cbff 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.155 2015/02/11 05:09:33 claudio Exp $ */ +/* $OpenBSD: sysctl.h,v 1.156 2015/07/18 15:51:17 mpi Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -942,9 +942,9 @@ int sysctl_rdstruct(void *, size_t *, void *, const void *, int); int sysctl_struct(void *, size_t *, void *, size_t, void *, int); int sysctl_file(int *, u_int, char *, size_t *, struct proc *); int sysctl_doproc(int *, u_int, char *, size_t *); -struct radix_node; +struct rtentry; struct walkarg; -int sysctl_dumpentry(struct radix_node *, void *, u_int); +int sysctl_dumpentry(struct rtentry *, void *, unsigned 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 *); |