xref: /netbsd-src/sys/net/rtbl.c (revision fd34ea77eb8af7799b3fb5a3f29af9eb231073c6)
1*fd34ea77Schs /*	$NetBSD: rtbl.c,v 1.7 2017/06/01 02:45:14 chs Exp $	*/
2060522deSdyoung 
3060522deSdyoung /*-
4060522deSdyoung  * Copyright (c) 1998, 2008, 2011 The NetBSD Foundation, Inc.
5060522deSdyoung  * All rights reserved.
6060522deSdyoung  *
7060522deSdyoung  * This code is derived from software contributed to The NetBSD Foundation
8060522deSdyoung  * by Kevin M. Lahey of the Numerical Aerospace Simulation Facility,
9060522deSdyoung  * NASA Ames Research Center.
10060522deSdyoung  *
11060522deSdyoung  * Redistribution and use in source and binary forms, with or without
12060522deSdyoung  * modification, are permitted provided that the following conditions
13060522deSdyoung  * are met:
14060522deSdyoung  * 1. Redistributions of source code must retain the above copyright
15060522deSdyoung  *    notice, this list of conditions and the following disclaimer.
16060522deSdyoung  * 2. Redistributions in binary form must reproduce the above copyright
17060522deSdyoung  *    notice, this list of conditions and the following disclaimer in the
18060522deSdyoung  *    documentation and/or other materials provided with the distribution.
19060522deSdyoung  *
20060522deSdyoung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21060522deSdyoung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22060522deSdyoung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23060522deSdyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24060522deSdyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25060522deSdyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26060522deSdyoung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27060522deSdyoung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28060522deSdyoung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29060522deSdyoung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30060522deSdyoung  * POSSIBILITY OF SUCH DAMAGE.
31060522deSdyoung  */
32060522deSdyoung 
33060522deSdyoung /*
34060522deSdyoung  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
35060522deSdyoung  * All rights reserved.
36060522deSdyoung  *
37060522deSdyoung  * Redistribution and use in source and binary forms, with or without
38060522deSdyoung  * modification, are permitted provided that the following conditions
39060522deSdyoung  * are met:
40060522deSdyoung  * 1. Redistributions of source code must retain the above copyright
41060522deSdyoung  *    notice, this list of conditions and the following disclaimer.
42060522deSdyoung  * 2. Redistributions in binary form must reproduce the above copyright
43060522deSdyoung  *    notice, this list of conditions and the following disclaimer in the
44060522deSdyoung  *    documentation and/or other materials provided with the distribution.
45060522deSdyoung  * 3. Neither the name of the project nor the names of its contributors
46060522deSdyoung  *    may be used to endorse or promote products derived from this software
47060522deSdyoung  *    without specific prior written permission.
48060522deSdyoung  *
49060522deSdyoung  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
50060522deSdyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51060522deSdyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52060522deSdyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
53060522deSdyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54060522deSdyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55060522deSdyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56060522deSdyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57060522deSdyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58060522deSdyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59060522deSdyoung  * SUCH DAMAGE.
60060522deSdyoung  */
61060522deSdyoung 
62060522deSdyoung /*
63060522deSdyoung  * Copyright (c) 1980, 1986, 1991, 1993
64060522deSdyoung  *	The Regents of the University of California.  All rights reserved.
65060522deSdyoung  *
66060522deSdyoung  * Redistribution and use in source and binary forms, with or without
67060522deSdyoung  * modification, are permitted provided that the following conditions
68060522deSdyoung  * are met:
69060522deSdyoung  * 1. Redistributions of source code must retain the above copyright
70060522deSdyoung  *    notice, this list of conditions and the following disclaimer.
71060522deSdyoung  * 2. Redistributions in binary form must reproduce the above copyright
72060522deSdyoung  *    notice, this list of conditions and the following disclaimer in the
73060522deSdyoung  *    documentation and/or other materials provided with the distribution.
74060522deSdyoung  * 3. Neither the name of the University nor the names of its contributors
75060522deSdyoung  *    may be used to endorse or promote products derived from this software
76060522deSdyoung  *    without specific prior written permission.
77060522deSdyoung  *
78060522deSdyoung  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79060522deSdyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80060522deSdyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81060522deSdyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82060522deSdyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83060522deSdyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84060522deSdyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85060522deSdyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86060522deSdyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87060522deSdyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88060522deSdyoung  * SUCH DAMAGE.
89060522deSdyoung  *
90060522deSdyoung  *	@(#)route.c	8.3 (Berkeley) 1/9/95
91060522deSdyoung  */
92060522deSdyoung 
931c4a50f1Spooka #if defined(_KERNEL) && defined(_KERNEL_OPT)
94060522deSdyoung #include "opt_route.h"
951c4a50f1Spooka #endif /* _KERNEL && _KERNEL_OPT */
96060522deSdyoung 
97060522deSdyoung #include <sys/cdefs.h>
98*fd34ea77Schs __KERNEL_RCSID(0, "$NetBSD: rtbl.c,v 1.7 2017/06/01 02:45:14 chs Exp $");
99060522deSdyoung 
100060522deSdyoung #include <sys/param.h>
101060522deSdyoung #include <sys/kmem.h>
102060522deSdyoung #include <sys/sysctl.h>
103060522deSdyoung #include <sys/systm.h>
104060522deSdyoung #include <sys/callout.h>
105060522deSdyoung #include <sys/proc.h>
106060522deSdyoung #include <sys/mbuf.h>
107060522deSdyoung #include <sys/socket.h>
108060522deSdyoung #include <sys/socketvar.h>
109060522deSdyoung #include <sys/domain.h>
110060522deSdyoung #include <sys/kernel.h>
111060522deSdyoung #include <sys/ioctl.h>
112060522deSdyoung #include <sys/pool.h>
113060522deSdyoung #include <sys/kauth.h>
114060522deSdyoung 
115060522deSdyoung #include <net/if.h>
116060522deSdyoung #include <net/if_dl.h>
117060522deSdyoung #include <net/route.h>
118060522deSdyoung #include <net/raw_cb.h>
119060522deSdyoung 
120060522deSdyoung static rtbl_t *rt_tables[AF_MAX+1];
121060522deSdyoung 
122060522deSdyoung int
rt_inithead(rtbl_t ** tp,int off)123060522deSdyoung rt_inithead(rtbl_t **tp, int off)
124060522deSdyoung {
125060522deSdyoung 	rtbl_t *t;
126060522deSdyoung 	if (*tp != NULL)
127060522deSdyoung 		return 1;
128*fd34ea77Schs 	t = kmem_alloc(sizeof(*t), KM_SLEEP);
129060522deSdyoung 	*tp = t;
130060522deSdyoung 	return rn_inithead0(&t->t_rnh, off);
131060522deSdyoung }
132060522deSdyoung 
133060522deSdyoung struct rtentry *
rt_matchaddr(rtbl_t * t,const struct sockaddr * dst)134060522deSdyoung rt_matchaddr(rtbl_t *t, const struct sockaddr *dst)
135060522deSdyoung {
136060522deSdyoung 	struct radix_node_head *rnh = &t->t_rnh;
137060522deSdyoung 	struct radix_node *rn;
138060522deSdyoung 
139060522deSdyoung 	rn = rnh->rnh_matchaddr(dst, rnh);
140060522deSdyoung 	if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
141060522deSdyoung 		return NULL;
142060522deSdyoung 	return (struct rtentry *)rn;
143060522deSdyoung }
144060522deSdyoung 
145060522deSdyoung int
rt_addaddr(rtbl_t * t,struct rtentry * rt,const struct sockaddr * netmask)146060522deSdyoung rt_addaddr(rtbl_t *t, struct rtentry *rt, const struct sockaddr *netmask)
147060522deSdyoung {
148060522deSdyoung 	struct radix_node_head *rnh = &t->t_rnh;
149060522deSdyoung 	struct radix_node *rn;
150060522deSdyoung 
151060522deSdyoung 	rn = rnh->rnh_addaddr(rt_getkey(rt), netmask, rnh, rt->rt_nodes);
152060522deSdyoung 
153060522deSdyoung 	return (rn == NULL) ? EEXIST : 0;
154060522deSdyoung }
155060522deSdyoung 
156060522deSdyoung struct rtentry *
rt_lookup(rtbl_t * t,const struct sockaddr * dst,const struct sockaddr * netmask)157060522deSdyoung rt_lookup(rtbl_t *t, const struct sockaddr *dst, const struct sockaddr *netmask)
158060522deSdyoung {
159060522deSdyoung 	struct radix_node_head *rnh = &t->t_rnh;
160060522deSdyoung 	struct radix_node *rn;
161060522deSdyoung 
162060522deSdyoung 	rn = rnh->rnh_lookup(dst, netmask, rnh);
163060522deSdyoung 	if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
164060522deSdyoung 		return NULL;
165060522deSdyoung 	return (struct rtentry *)rn;
166060522deSdyoung }
167060522deSdyoung 
168060522deSdyoung struct rtentry *
rt_deladdr(rtbl_t * t,const struct sockaddr * dst,const struct sockaddr * netmask)169060522deSdyoung rt_deladdr(rtbl_t *t, const struct sockaddr *dst,
170060522deSdyoung     const struct sockaddr *netmask)
171060522deSdyoung {
172060522deSdyoung 	struct radix_node_head *rnh = &t->t_rnh;
173060522deSdyoung 	struct radix_node *rn;
174060522deSdyoung 
175060522deSdyoung 	if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)
176060522deSdyoung 		return NULL;
177060522deSdyoung 	if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
178060522deSdyoung 		panic("%s", __func__);
179060522deSdyoung 	return (struct rtentry *)rn;
180060522deSdyoung }
181060522deSdyoung 
182060522deSdyoung static int
rt_walktree_visitor(struct radix_node * rn,void * v)183060522deSdyoung rt_walktree_visitor(struct radix_node *rn, void *v)
184060522deSdyoung {
185060522deSdyoung 	struct rtwalk *rw = (struct rtwalk *)v;
186060522deSdyoung 
187060522deSdyoung 	return (*rw->rw_f)((struct rtentry *)rn, rw->rw_v);
188060522deSdyoung }
189060522deSdyoung 
190060522deSdyoung int
rtbl_walktree(sa_family_t family,int (* f)(struct rtentry *,void *),void * v)1916fb88806Sozaki-r rtbl_walktree(sa_family_t family, int (*f)(struct rtentry *, void *), void *v)
192060522deSdyoung {
193060522deSdyoung 	rtbl_t *t = rt_tables[family];
194060522deSdyoung 	struct rtwalk rw;
195060522deSdyoung 
196060522deSdyoung 	if (t == NULL)
197060522deSdyoung 		return 0;
198060522deSdyoung 
199060522deSdyoung 	rw.rw_f = f;
200060522deSdyoung 	rw.rw_v = v;
201060522deSdyoung 
202060522deSdyoung 	return rn_walktree(&t->t_rnh, rt_walktree_visitor, &rw);
203060522deSdyoung }
204060522deSdyoung 
2055879478fSozaki-r struct rtentry *
rtbl_search_matched_entry(sa_family_t family,int (* f)(struct rtentry *,void *),void * v)2065879478fSozaki-r rtbl_search_matched_entry(sa_family_t family,
2075879478fSozaki-r     int (*f)(struct rtentry *, void *), void *v)
2085879478fSozaki-r {
2095879478fSozaki-r 	rtbl_t *t = rt_tables[family];
2105879478fSozaki-r 	struct rtwalk rw;
2115879478fSozaki-r 
2125879478fSozaki-r 	if (t == NULL)
2135879478fSozaki-r 		return 0;
2145879478fSozaki-r 
2155879478fSozaki-r 	rw.rw_f = f;
2165879478fSozaki-r 	rw.rw_v = v;
2175879478fSozaki-r 
2185879478fSozaki-r 	return (struct rtentry *)
2195879478fSozaki-r 	    rn_search_matched(&t->t_rnh, rt_walktree_visitor, &rw);
2205879478fSozaki-r }
2215879478fSozaki-r 
222060522deSdyoung rtbl_t *
rt_gettable(sa_family_t af)223060522deSdyoung rt_gettable(sa_family_t af)
224060522deSdyoung {
225060522deSdyoung 	if (af >= __arraycount(rt_tables))
226060522deSdyoung 		return NULL;
227060522deSdyoung 	return rt_tables[af];
228060522deSdyoung }
229060522deSdyoung 
230060522deSdyoung void
rtbl_init(void)231060522deSdyoung rtbl_init(void)
232060522deSdyoung {
233060522deSdyoung 	struct domain *dom;
234060522deSdyoung 	DOMAIN_FOREACH(dom)
235060522deSdyoung 		if (dom->dom_rtattach)
236060522deSdyoung 			dom->dom_rtattach(&rt_tables[dom->dom_family],
237060522deSdyoung 			    dom->dom_rtoffset);
238060522deSdyoung }
239060522deSdyoung 
240060522deSdyoung void
rt_assert_inactive(const struct rtentry * rt)241060522deSdyoung rt_assert_inactive(const struct rtentry *rt)
242060522deSdyoung {
243060522deSdyoung 	if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
244060522deSdyoung 		panic ("rtfree 2");
245060522deSdyoung }
2466a7ab186Sozaki-r 
2476a7ab186Sozaki-r int
rt_refines(const struct sockaddr * m_sa,const struct sockaddr * n_sa)2486a7ab186Sozaki-r rt_refines(const struct sockaddr *m_sa, const struct sockaddr *n_sa)
2496a7ab186Sozaki-r {
2506a7ab186Sozaki-r 
2516a7ab186Sozaki-r 	return rn_refines(m_sa, n_sa);
2526a7ab186Sozaki-r }
253