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