1 | /* $NetBSD: rtbl.c,v 1.7 2017/06/01 02:45:14 chs 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.7 2017/06/01 02:45:14 chs 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/kernel.h> |
111 | #include <sys/ioctl.h> |
112 | #include <sys/pool.h> |
113 | #include <sys/kauth.h> |
114 | |
115 | #include <net/if.h> |
116 | #include <net/if_dl.h> |
117 | #include <net/route.h> |
118 | #include <net/raw_cb.h> |
119 | |
120 | static rtbl_t *rt_tables[AF_MAX+1]; |
121 | |
122 | int |
123 | rt_inithead(rtbl_t **tp, int off) |
124 | { |
125 | rtbl_t *t; |
126 | if (*tp != NULL) |
127 | return 1; |
128 | t = kmem_alloc(sizeof(*t), KM_SLEEP); |
129 | *tp = t; |
130 | return rn_inithead0(&t->t_rnh, off); |
131 | } |
132 | |
133 | struct rtentry * |
134 | rt_matchaddr(rtbl_t *t, const struct sockaddr *dst) |
135 | { |
136 | struct radix_node_head *rnh = &t->t_rnh; |
137 | struct radix_node *rn; |
138 | |
139 | rn = rnh->rnh_matchaddr(dst, rnh); |
140 | if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) |
141 | return NULL; |
142 | return (struct rtentry *)rn; |
143 | } |
144 | |
145 | int |
146 | rt_addaddr(rtbl_t *t, struct rtentry *rt, const struct sockaddr *netmask) |
147 | { |
148 | struct radix_node_head *rnh = &t->t_rnh; |
149 | struct radix_node *rn; |
150 | |
151 | rn = rnh->rnh_addaddr(rt_getkey(rt), netmask, rnh, rt->rt_nodes); |
152 | |
153 | return (rn == NULL) ? EEXIST : 0; |
154 | } |
155 | |
156 | struct rtentry * |
157 | rt_lookup(rtbl_t *t, const struct sockaddr *dst, const struct sockaddr *netmask) |
158 | { |
159 | struct radix_node_head *rnh = &t->t_rnh; |
160 | struct radix_node *rn; |
161 | |
162 | rn = rnh->rnh_lookup(dst, netmask, rnh); |
163 | if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) |
164 | return NULL; |
165 | return (struct rtentry *)rn; |
166 | } |
167 | |
168 | struct rtentry * |
169 | rt_deladdr(rtbl_t *t, const struct sockaddr *dst, |
170 | const struct sockaddr *netmask) |
171 | { |
172 | struct radix_node_head *rnh = &t->t_rnh; |
173 | struct radix_node *rn; |
174 | |
175 | if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL) |
176 | return NULL; |
177 | if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) |
178 | panic("%s" , __func__); |
179 | return (struct rtentry *)rn; |
180 | } |
181 | |
182 | static int |
183 | rt_walktree_visitor(struct radix_node *rn, void *v) |
184 | { |
185 | struct rtwalk *rw = (struct rtwalk *)v; |
186 | |
187 | return (*rw->rw_f)((struct rtentry *)rn, rw->rw_v); |
188 | } |
189 | |
190 | int |
191 | rtbl_walktree(sa_family_t family, int (*f)(struct rtentry *, void *), void *v) |
192 | { |
193 | rtbl_t *t = rt_tables[family]; |
194 | struct rtwalk rw; |
195 | |
196 | if (t == NULL) |
197 | return 0; |
198 | |
199 | rw.rw_f = f; |
200 | rw.rw_v = v; |
201 | |
202 | return rn_walktree(&t->t_rnh, rt_walktree_visitor, &rw); |
203 | } |
204 | |
205 | struct rtentry * |
206 | rtbl_search_matched_entry(sa_family_t family, |
207 | int (*f)(struct rtentry *, void *), void *v) |
208 | { |
209 | rtbl_t *t = rt_tables[family]; |
210 | struct rtwalk rw; |
211 | |
212 | if (t == NULL) |
213 | return 0; |
214 | |
215 | rw.rw_f = f; |
216 | rw.rw_v = v; |
217 | |
218 | return (struct rtentry *) |
219 | rn_search_matched(&t->t_rnh, rt_walktree_visitor, &rw); |
220 | } |
221 | |
222 | rtbl_t * |
223 | rt_gettable(sa_family_t af) |
224 | { |
225 | if (af >= __arraycount(rt_tables)) |
226 | return NULL; |
227 | return rt_tables[af]; |
228 | } |
229 | |
230 | void |
231 | rtbl_init(void) |
232 | { |
233 | struct domain *dom; |
234 | DOMAIN_FOREACH(dom) |
235 | if (dom->dom_rtattach) |
236 | dom->dom_rtattach(&rt_tables[dom->dom_family], |
237 | dom->dom_rtoffset); |
238 | } |
239 | |
240 | void |
241 | rt_assert_inactive(const struct rtentry *rt) |
242 | { |
243 | if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) |
244 | panic ("rtfree 2" ); |
245 | } |
246 | |
247 | int |
248 | rt_refines(const struct sockaddr *m_sa, const struct sockaddr *n_sa) |
249 | { |
250 | |
251 | return rn_refines(m_sa, n_sa); |
252 | } |
253 | |