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