Home | History | Annotate | Line # | Download | only in net
rtbl.c revision 1.1.18.1
      1  1.1.18.1  jdolecek /*	$NetBSD: rtbl.c,v 1.1.18.1 2017/12/03 11:39:02 jdolecek Exp $	*/
      2       1.1    dyoung 
      3       1.1    dyoung /*-
      4       1.1    dyoung  * Copyright (c) 1998, 2008, 2011 The NetBSD Foundation, Inc.
      5       1.1    dyoung  * All rights reserved.
      6       1.1    dyoung  *
      7       1.1    dyoung  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1    dyoung  * by Kevin M. Lahey of the Numerical Aerospace Simulation Facility,
      9       1.1    dyoung  * NASA Ames Research Center.
     10       1.1    dyoung  *
     11       1.1    dyoung  * Redistribution and use in source and binary forms, with or without
     12       1.1    dyoung  * modification, are permitted provided that the following conditions
     13       1.1    dyoung  * are met:
     14       1.1    dyoung  * 1. Redistributions of source code must retain the above copyright
     15       1.1    dyoung  *    notice, this list of conditions and the following disclaimer.
     16       1.1    dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1    dyoung  *    notice, this list of conditions and the following disclaimer in the
     18       1.1    dyoung  *    documentation and/or other materials provided with the distribution.
     19       1.1    dyoung  *
     20       1.1    dyoung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21       1.1    dyoung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22       1.1    dyoung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23       1.1    dyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24       1.1    dyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25       1.1    dyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26       1.1    dyoung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27       1.1    dyoung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28       1.1    dyoung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29       1.1    dyoung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30       1.1    dyoung  * POSSIBILITY OF SUCH DAMAGE.
     31       1.1    dyoung  */
     32       1.1    dyoung 
     33       1.1    dyoung /*
     34       1.1    dyoung  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
     35       1.1    dyoung  * All rights reserved.
     36       1.1    dyoung  *
     37       1.1    dyoung  * Redistribution and use in source and binary forms, with or without
     38       1.1    dyoung  * modification, are permitted provided that the following conditions
     39       1.1    dyoung  * are met:
     40       1.1    dyoung  * 1. Redistributions of source code must retain the above copyright
     41       1.1    dyoung  *    notice, this list of conditions and the following disclaimer.
     42       1.1    dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     43       1.1    dyoung  *    notice, this list of conditions and the following disclaimer in the
     44       1.1    dyoung  *    documentation and/or other materials provided with the distribution.
     45       1.1    dyoung  * 3. Neither the name of the project nor the names of its contributors
     46       1.1    dyoung  *    may be used to endorse or promote products derived from this software
     47       1.1    dyoung  *    without specific prior written permission.
     48       1.1    dyoung  *
     49       1.1    dyoung  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     50       1.1    dyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     51       1.1    dyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     52       1.1    dyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     53       1.1    dyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     54       1.1    dyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     55       1.1    dyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     56       1.1    dyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     57       1.1    dyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     58       1.1    dyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     59       1.1    dyoung  * SUCH DAMAGE.
     60       1.1    dyoung  */
     61       1.1    dyoung 
     62       1.1    dyoung /*
     63       1.1    dyoung  * Copyright (c) 1980, 1986, 1991, 1993
     64       1.1    dyoung  *	The Regents of the University of California.  All rights reserved.
     65       1.1    dyoung  *
     66       1.1    dyoung  * Redistribution and use in source and binary forms, with or without
     67       1.1    dyoung  * modification, are permitted provided that the following conditions
     68       1.1    dyoung  * are met:
     69       1.1    dyoung  * 1. Redistributions of source code must retain the above copyright
     70       1.1    dyoung  *    notice, this list of conditions and the following disclaimer.
     71       1.1    dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     72       1.1    dyoung  *    notice, this list of conditions and the following disclaimer in the
     73       1.1    dyoung  *    documentation and/or other materials provided with the distribution.
     74       1.1    dyoung  * 3. Neither the name of the University nor the names of its contributors
     75       1.1    dyoung  *    may be used to endorse or promote products derived from this software
     76       1.1    dyoung  *    without specific prior written permission.
     77       1.1    dyoung  *
     78       1.1    dyoung  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     79       1.1    dyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     80       1.1    dyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     81       1.1    dyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     82       1.1    dyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     83       1.1    dyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     84       1.1    dyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     85       1.1    dyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     86       1.1    dyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     87       1.1    dyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     88       1.1    dyoung  * SUCH DAMAGE.
     89       1.1    dyoung  *
     90       1.1    dyoung  *	@(#)route.c	8.3 (Berkeley) 1/9/95
     91       1.1    dyoung  */
     92       1.1    dyoung 
     93  1.1.18.1  jdolecek #if defined(_KERNEL) && defined(_KERNEL_OPT)
     94       1.1    dyoung #include "opt_route.h"
     95  1.1.18.1  jdolecek #endif /* _KERNEL && _KERNEL_OPT */
     96       1.1    dyoung 
     97       1.1    dyoung #include <sys/cdefs.h>
     98       1.1    dyoung __KERNEL_RCSID(0, "$NetBSD: rtbl.c,v 1.1.18.1 2017/12/03 11:39:02 jdolecek Exp $");
     99       1.1    dyoung 
    100       1.1    dyoung #include <sys/param.h>
    101       1.1    dyoung #include <sys/kmem.h>
    102       1.1    dyoung #include <sys/sysctl.h>
    103       1.1    dyoung #include <sys/systm.h>
    104       1.1    dyoung #include <sys/callout.h>
    105       1.1    dyoung #include <sys/proc.h>
    106       1.1    dyoung #include <sys/mbuf.h>
    107       1.1    dyoung #include <sys/socket.h>
    108       1.1    dyoung #include <sys/socketvar.h>
    109       1.1    dyoung #include <sys/domain.h>
    110       1.1    dyoung #include <sys/kernel.h>
    111       1.1    dyoung #include <sys/ioctl.h>
    112       1.1    dyoung #include <sys/pool.h>
    113       1.1    dyoung #include <sys/kauth.h>
    114       1.1    dyoung 
    115       1.1    dyoung #include <net/if.h>
    116       1.1    dyoung #include <net/if_dl.h>
    117       1.1    dyoung #include <net/route.h>
    118       1.1    dyoung #include <net/raw_cb.h>
    119       1.1    dyoung 
    120       1.1    dyoung static rtbl_t *rt_tables[AF_MAX+1];
    121       1.1    dyoung 
    122       1.1    dyoung int
    123       1.1    dyoung rt_inithead(rtbl_t **tp, int off)
    124       1.1    dyoung {
    125       1.1    dyoung 	rtbl_t *t;
    126       1.1    dyoung 	if (*tp != NULL)
    127       1.1    dyoung 		return 1;
    128  1.1.18.1  jdolecek 	t = kmem_alloc(sizeof(*t), KM_SLEEP);
    129       1.1    dyoung 	*tp = t;
    130       1.1    dyoung 	return rn_inithead0(&t->t_rnh, off);
    131       1.1    dyoung }
    132       1.1    dyoung 
    133       1.1    dyoung struct rtentry *
    134       1.1    dyoung rt_matchaddr(rtbl_t *t, const struct sockaddr *dst)
    135       1.1    dyoung {
    136       1.1    dyoung 	struct radix_node_head *rnh = &t->t_rnh;
    137       1.1    dyoung 	struct radix_node *rn;
    138       1.1    dyoung 
    139       1.1    dyoung 	rn = rnh->rnh_matchaddr(dst, rnh);
    140       1.1    dyoung 	if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
    141       1.1    dyoung 		return NULL;
    142       1.1    dyoung 	return (struct rtentry *)rn;
    143       1.1    dyoung }
    144       1.1    dyoung 
    145       1.1    dyoung int
    146       1.1    dyoung rt_addaddr(rtbl_t *t, struct rtentry *rt, const struct sockaddr *netmask)
    147       1.1    dyoung {
    148       1.1    dyoung 	struct radix_node_head *rnh = &t->t_rnh;
    149       1.1    dyoung 	struct radix_node *rn;
    150       1.1    dyoung 
    151       1.1    dyoung 	rn = rnh->rnh_addaddr(rt_getkey(rt), netmask, rnh, rt->rt_nodes);
    152       1.1    dyoung 
    153       1.1    dyoung 	return (rn == NULL) ? EEXIST : 0;
    154       1.1    dyoung }
    155       1.1    dyoung 
    156       1.1    dyoung struct rtentry *
    157       1.1    dyoung rt_lookup(rtbl_t *t, const struct sockaddr *dst, const struct sockaddr *netmask)
    158       1.1    dyoung {
    159       1.1    dyoung 	struct radix_node_head *rnh = &t->t_rnh;
    160       1.1    dyoung 	struct radix_node *rn;
    161       1.1    dyoung 
    162       1.1    dyoung 	rn = rnh->rnh_lookup(dst, netmask, rnh);
    163       1.1    dyoung 	if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
    164       1.1    dyoung 		return NULL;
    165       1.1    dyoung 	return (struct rtentry *)rn;
    166       1.1    dyoung }
    167       1.1    dyoung 
    168       1.1    dyoung struct rtentry *
    169       1.1    dyoung rt_deladdr(rtbl_t *t, const struct sockaddr *dst,
    170       1.1    dyoung     const struct sockaddr *netmask)
    171       1.1    dyoung {
    172       1.1    dyoung 	struct radix_node_head *rnh = &t->t_rnh;
    173       1.1    dyoung 	struct radix_node *rn;
    174       1.1    dyoung 
    175       1.1    dyoung 	if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)
    176       1.1    dyoung 		return NULL;
    177       1.1    dyoung 	if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
    178       1.1    dyoung 		panic("%s", __func__);
    179       1.1    dyoung 	return (struct rtentry *)rn;
    180       1.1    dyoung }
    181       1.1    dyoung 
    182       1.1    dyoung static int
    183       1.1    dyoung rt_walktree_visitor(struct radix_node *rn, void *v)
    184       1.1    dyoung {
    185       1.1    dyoung 	struct rtwalk *rw = (struct rtwalk *)v;
    186       1.1    dyoung 
    187       1.1    dyoung 	return (*rw->rw_f)((struct rtentry *)rn, rw->rw_v);
    188       1.1    dyoung }
    189       1.1    dyoung 
    190       1.1    dyoung int
    191  1.1.18.1  jdolecek rtbl_walktree(sa_family_t family, int (*f)(struct rtentry *, void *), void *v)
    192       1.1    dyoung {
    193       1.1    dyoung 	rtbl_t *t = rt_tables[family];
    194       1.1    dyoung 	struct rtwalk rw;
    195       1.1    dyoung 
    196       1.1    dyoung 	if (t == NULL)
    197       1.1    dyoung 		return 0;
    198       1.1    dyoung 
    199       1.1    dyoung 	rw.rw_f = f;
    200       1.1    dyoung 	rw.rw_v = v;
    201       1.1    dyoung 
    202       1.1    dyoung 	return rn_walktree(&t->t_rnh, rt_walktree_visitor, &rw);
    203       1.1    dyoung }
    204       1.1    dyoung 
    205  1.1.18.1  jdolecek struct rtentry *
    206  1.1.18.1  jdolecek rtbl_search_matched_entry(sa_family_t family,
    207  1.1.18.1  jdolecek     int (*f)(struct rtentry *, void *), void *v)
    208  1.1.18.1  jdolecek {
    209  1.1.18.1  jdolecek 	rtbl_t *t = rt_tables[family];
    210  1.1.18.1  jdolecek 	struct rtwalk rw;
    211  1.1.18.1  jdolecek 
    212  1.1.18.1  jdolecek 	if (t == NULL)
    213  1.1.18.1  jdolecek 		return 0;
    214  1.1.18.1  jdolecek 
    215  1.1.18.1  jdolecek 	rw.rw_f = f;
    216  1.1.18.1  jdolecek 	rw.rw_v = v;
    217  1.1.18.1  jdolecek 
    218  1.1.18.1  jdolecek 	return (struct rtentry *)
    219  1.1.18.1  jdolecek 	    rn_search_matched(&t->t_rnh, rt_walktree_visitor, &rw);
    220  1.1.18.1  jdolecek }
    221  1.1.18.1  jdolecek 
    222       1.1    dyoung rtbl_t *
    223       1.1    dyoung rt_gettable(sa_family_t af)
    224       1.1    dyoung {
    225       1.1    dyoung 	if (af >= __arraycount(rt_tables))
    226       1.1    dyoung 		return NULL;
    227       1.1    dyoung 	return rt_tables[af];
    228       1.1    dyoung }
    229       1.1    dyoung 
    230       1.1    dyoung void
    231       1.1    dyoung rtbl_init(void)
    232       1.1    dyoung {
    233       1.1    dyoung 	struct domain *dom;
    234       1.1    dyoung 	DOMAIN_FOREACH(dom)
    235       1.1    dyoung 		if (dom->dom_rtattach)
    236       1.1    dyoung 			dom->dom_rtattach(&rt_tables[dom->dom_family],
    237       1.1    dyoung 			    dom->dom_rtoffset);
    238       1.1    dyoung }
    239       1.1    dyoung 
    240       1.1    dyoung void
    241       1.1    dyoung rt_assert_inactive(const struct rtentry *rt)
    242       1.1    dyoung {
    243       1.1    dyoung 	if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
    244       1.1    dyoung 		panic ("rtfree 2");
    245       1.1    dyoung }
    246  1.1.18.1  jdolecek 
    247  1.1.18.1  jdolecek int
    248  1.1.18.1  jdolecek rt_refines(const struct sockaddr *m_sa, const struct sockaddr *n_sa)
    249  1.1.18.1  jdolecek {
    250  1.1.18.1  jdolecek 
    251  1.1.18.1  jdolecek 	return rn_refines(m_sa, n_sa);
    252  1.1.18.1  jdolecek }
    253