/* $NetBSD: rtbl.c,v 1.7 2017/06/01 02:45:14 chs Exp $ */ /*- * Copyright (c) 1998, 2008, 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Kevin M. Lahey of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Copyright (c) 1980, 1986, 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)route.c 8.3 (Berkeley) 1/9/95 */ #if defined(_KERNEL) && defined(_KERNEL_OPT) #include "opt_route.h" #endif /* _KERNEL && _KERNEL_OPT */ #include __KERNEL_RCSID(0, "$NetBSD: rtbl.c,v 1.7 2017/06/01 02:45:14 chs Exp $"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static rtbl_t *rt_tables[AF_MAX+1]; int rt_inithead(rtbl_t **tp, int off) { rtbl_t *t; if (*tp != NULL) return 1; t = kmem_alloc(sizeof(*t), KM_SLEEP); *tp = t; return rn_inithead0(&t->t_rnh, off); } struct rtentry * rt_matchaddr(rtbl_t *t, const struct sockaddr *dst) { struct radix_node_head *rnh = &t->t_rnh; struct radix_node *rn; rn = rnh->rnh_matchaddr(dst, rnh); if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) return NULL; return (struct rtentry *)rn; } int rt_addaddr(rtbl_t *t, struct rtentry *rt, const struct sockaddr *netmask) { struct radix_node_head *rnh = &t->t_rnh; struct radix_node *rn; rn = rnh->rnh_addaddr(rt_getkey(rt), netmask, rnh, rt->rt_nodes); return (rn == NULL) ? EEXIST : 0; } struct rtentry * rt_lookup(rtbl_t *t, const struct sockaddr *dst, const struct sockaddr *netmask) { struct radix_node_head *rnh = &t->t_rnh; struct radix_node *rn; rn = rnh->rnh_lookup(dst, netmask, rnh); if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) return NULL; return (struct rtentry *)rn; } struct rtentry * rt_deladdr(rtbl_t *t, const struct sockaddr *dst, const struct sockaddr *netmask) { struct radix_node_head *rnh = &t->t_rnh; struct radix_node *rn; if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL) return NULL; if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) panic("%s", __func__); return (struct rtentry *)rn; } static int rt_walktree_visitor(struct radix_node *rn, void *v) { struct rtwalk *rw = (struct rtwalk *)v; return (*rw->rw_f)((struct rtentry *)rn, rw->rw_v); } int rtbl_walktree(sa_family_t family, int (*f)(struct rtentry *, void *), void *v) { rtbl_t *t = rt_tables[family]; struct rtwalk rw; if (t == NULL) return 0; rw.rw_f = f; rw.rw_v = v; return rn_walktree(&t->t_rnh, rt_walktree_visitor, &rw); } struct rtentry * rtbl_search_matched_entry(sa_family_t family, int (*f)(struct rtentry *, void *), void *v) { rtbl_t *t = rt_tables[family]; struct rtwalk rw; if (t == NULL) return 0; rw.rw_f = f; rw.rw_v = v; return (struct rtentry *) rn_search_matched(&t->t_rnh, rt_walktree_visitor, &rw); } rtbl_t * rt_gettable(sa_family_t af) { if (af >= __arraycount(rt_tables)) return NULL; return rt_tables[af]; } void rtbl_init(void) { struct domain *dom; DOMAIN_FOREACH(dom) if (dom->dom_rtattach) dom->dom_rtattach(&rt_tables[dom->dom_family], dom->dom_rtoffset); } void rt_assert_inactive(const struct rtentry *rt) { if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) panic ("rtfree 2"); } int rt_refines(const struct sockaddr *m_sa, const struct sockaddr *n_sa) { return rn_refines(m_sa, n_sa); }