Deleted Added
full compact
route.c (191734) route.c (193232)
1/*-
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95
1/*-
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95
30 * $FreeBSD: head/sys/net/route.c 191734 2009-05-02 05:02:28Z zec $
30 * $FreeBSD: head/sys/net/route.c 193232 2009-06-01 15:49:42Z bz $
31 */
32/************************************************************************
33 * Note: In this file a 'fib' is a "forwarding information base" *
34 * Which is the new name for an in kernel routing (next hop) table. *
35 ***********************************************************************/
36
37#include "opt_inet.h"
38#include "opt_route.h"
39#include "opt_mrouting.h"
40#include "opt_mpath.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/syslog.h>
45#include <sys/malloc.h>
46#include <sys/mbuf.h>
47#include <sys/socket.h>
48#include <sys/sysctl.h>
49#include <sys/syslog.h>
50#include <sys/sysproto.h>
51#include <sys/proc.h>
52#include <sys/domain.h>
53#include <sys/kernel.h>
54#include <sys/vimage.h>
55
56#include <net/if.h>
57#include <net/if_dl.h>
58#include <net/route.h>
59
60#ifdef RADIX_MPATH
61#include <net/radix_mpath.h>
62#endif
63#include <net/vnet.h>
64
65#include <netinet/in.h>
66#include <netinet/ip_mroute.h>
67#include <netinet/vinet.h>
68
69#include <vm/uma.h>
70
71u_int rt_numfibs = RT_NUMFIBS;
72SYSCTL_INT(_net, OID_AUTO, fibs, CTLFLAG_RD, &rt_numfibs, 0, "");
73/*
74 * Allow the boot code to allow LESS than RT_MAXFIBS to be used.
75 * We can't do more because storage is statically allocated for now.
76 * (for compatibility reasons.. this will change).
77 */
78TUNABLE_INT("net.fibs", &rt_numfibs);
79
80/*
81 * By default add routes to all fibs for new interfaces.
82 * Once this is set to 0 then only allocate routes on interface
83 * changes for the FIB of the caller when adding a new set of addresses
84 * to an interface. XXX this is a shotgun aproach to a problem that needs
85 * a more fine grained solution.. that will come.
86 */
87u_int rt_add_addr_allfibs = 1;
88SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
89 &rt_add_addr_allfibs, 0, "");
90TUNABLE_INT("net.add_addr_allfibs", &rt_add_addr_allfibs);
91
92#ifdef VIMAGE_GLOBALS
93static struct rtstat rtstat;
31 */
32/************************************************************************
33 * Note: In this file a 'fib' is a "forwarding information base" *
34 * Which is the new name for an in kernel routing (next hop) table. *
35 ***********************************************************************/
36
37#include "opt_inet.h"
38#include "opt_route.h"
39#include "opt_mrouting.h"
40#include "opt_mpath.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/syslog.h>
45#include <sys/malloc.h>
46#include <sys/mbuf.h>
47#include <sys/socket.h>
48#include <sys/sysctl.h>
49#include <sys/syslog.h>
50#include <sys/sysproto.h>
51#include <sys/proc.h>
52#include <sys/domain.h>
53#include <sys/kernel.h>
54#include <sys/vimage.h>
55
56#include <net/if.h>
57#include <net/if_dl.h>
58#include <net/route.h>
59
60#ifdef RADIX_MPATH
61#include <net/radix_mpath.h>
62#endif
63#include <net/vnet.h>
64
65#include <netinet/in.h>
66#include <netinet/ip_mroute.h>
67#include <netinet/vinet.h>
68
69#include <vm/uma.h>
70
71u_int rt_numfibs = RT_NUMFIBS;
72SYSCTL_INT(_net, OID_AUTO, fibs, CTLFLAG_RD, &rt_numfibs, 0, "");
73/*
74 * Allow the boot code to allow LESS than RT_MAXFIBS to be used.
75 * We can't do more because storage is statically allocated for now.
76 * (for compatibility reasons.. this will change).
77 */
78TUNABLE_INT("net.fibs", &rt_numfibs);
79
80/*
81 * By default add routes to all fibs for new interfaces.
82 * Once this is set to 0 then only allocate routes on interface
83 * changes for the FIB of the caller when adding a new set of addresses
84 * to an interface. XXX this is a shotgun aproach to a problem that needs
85 * a more fine grained solution.. that will come.
86 */
87u_int rt_add_addr_allfibs = 1;
88SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
89 &rt_add_addr_allfibs, 0, "");
90TUNABLE_INT("net.add_addr_allfibs", &rt_add_addr_allfibs);
91
92#ifdef VIMAGE_GLOBALS
93static struct rtstat rtstat;
94struct radix_node_head *rt_tables;
94
95
95/* by default only the first 'row' of tables will be accessed. */
96/*
97 * XXXMRT When we fix netstat, and do this differnetly,
98 * we can allocate this dynamically. As long as we are keeping
99 * things backwards compaitble we need to allocate this
100 * statically.
101 */
102struct radix_node_head *rt_tables[RT_MAXFIBS][AF_MAX+1];
103
104static int rttrash; /* routes not in table but not freed */
105#endif
106
107static void rt_maskedcopy(struct sockaddr *,
108 struct sockaddr *, struct sockaddr *);
109static int vnet_route_iattach(const void *);
110
111#ifndef VIMAGE_GLOBALS
112static const vnet_modinfo_t vnet_rtable_modinfo = {
113 .vmi_id = VNET_MOD_RTABLE,
114 .vmi_name = "rtable",
115 .vmi_iattach = vnet_route_iattach
116};
117#endif /* !VIMAGE_GLOBALS */
118
119/* compare two sockaddr structures */
120#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
121
122/*
123 * Convert a 'struct radix_node *' to a 'struct rtentry *'.
124 * The operation can be done safely (in this code) because a
125 * 'struct rtentry' starts with two 'struct radix_node''s, the first
126 * one representing leaf nodes in the routing tree, which is
127 * what the code in radix.c passes us as a 'struct radix_node'.
128 *
129 * But because there are a lot of assumptions in this conversion,
130 * do not cast explicitly, but always use the macro below.
131 */
132#define RNTORT(p) ((struct rtentry *)(p))
133
134#ifdef VIMAGE_GLOBALS
135static uma_zone_t rtzone; /* Routing table UMA zone. */
136#endif
137
138#if 0
139/* default fib for tunnels to use */
140u_int tunnel_fib = 0;
141SYSCTL_INT(_net, OID_AUTO, tunnelfib, CTLFLAG_RD, &tunnel_fib, 0, "");
142#endif
143
144/*
145 * handler for net.my_fibnum
146 */
147static int
148sysctl_my_fibnum(SYSCTL_HANDLER_ARGS)
149{
150 int fibnum;
151 int error;
152
153 fibnum = curthread->td_proc->p_fibnum;
154 error = sysctl_handle_int(oidp, &fibnum, 0, req);
155 return (error);
156}
157
158SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
159 NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller");
160
96static int rttrash; /* routes not in table but not freed */
97#endif
98
99static void rt_maskedcopy(struct sockaddr *,
100 struct sockaddr *, struct sockaddr *);
101static int vnet_route_iattach(const void *);
102
103#ifndef VIMAGE_GLOBALS
104static const vnet_modinfo_t vnet_rtable_modinfo = {
105 .vmi_id = VNET_MOD_RTABLE,
106 .vmi_name = "rtable",
107 .vmi_iattach = vnet_route_iattach
108};
109#endif /* !VIMAGE_GLOBALS */
110
111/* compare two sockaddr structures */
112#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
113
114/*
115 * Convert a 'struct radix_node *' to a 'struct rtentry *'.
116 * The operation can be done safely (in this code) because a
117 * 'struct rtentry' starts with two 'struct radix_node''s, the first
118 * one representing leaf nodes in the routing tree, which is
119 * what the code in radix.c passes us as a 'struct radix_node'.
120 *
121 * But because there are a lot of assumptions in this conversion,
122 * do not cast explicitly, but always use the macro below.
123 */
124#define RNTORT(p) ((struct rtentry *)(p))
125
126#ifdef VIMAGE_GLOBALS
127static uma_zone_t rtzone; /* Routing table UMA zone. */
128#endif
129
130#if 0
131/* default fib for tunnels to use */
132u_int tunnel_fib = 0;
133SYSCTL_INT(_net, OID_AUTO, tunnelfib, CTLFLAG_RD, &tunnel_fib, 0, "");
134#endif
135
136/*
137 * handler for net.my_fibnum
138 */
139static int
140sysctl_my_fibnum(SYSCTL_HANDLER_ARGS)
141{
142 int fibnum;
143 int error;
144
145 fibnum = curthread->td_proc->p_fibnum;
146 error = sysctl_handle_int(oidp, &fibnum, 0, req);
147 return (error);
148}
149
150SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
151 NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller");
152
153static __inline struct radix_node_head **
154rt_tables_get_rnh_ptr(int table, int fam)
155{
156 INIT_VNET_NET(curvnet);
157 struct radix_node_head **rnh;
158
159 KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
160 __func__));
161 KASSERT(fam >= 0 && fam < (AF_MAX+1), ("%s: fam out of bounds.",
162 __func__));
163
164 /* rnh is [fib=0][af=0]. */
165 rnh = (struct radix_node_head **)V_rt_tables;
166 /* Get the offset to the requested table and fam. */
167 rnh += table * (AF_MAX+1) + fam;
168
169 return (rnh);
170}
171
172struct radix_node_head *
173rt_tables_get_rnh(int table, int fam)
174{
175
176 return (*rt_tables_get_rnh_ptr(table, fam));
177}
178
161static void
162route_init(void)
163{
164
165 /* whack the tunable ints into line. */
166 if (rt_numfibs > RT_MAXFIBS)
167 rt_numfibs = RT_MAXFIBS;
168 if (rt_numfibs == 0)
169 rt_numfibs = 1;
170 rn_init(); /* initialize all zeroes, all ones, mask table */
171
172#ifndef VIMAGE_GLOBALS
173 vnet_mod_register(&vnet_rtable_modinfo);
174#else
175 vnet_route_iattach(NULL);
176#endif
177}
178
179static int vnet_route_iattach(const void *unused __unused)
180{
181 INIT_VNET_NET(curvnet);
179static void
180route_init(void)
181{
182
183 /* whack the tunable ints into line. */
184 if (rt_numfibs > RT_MAXFIBS)
185 rt_numfibs = RT_MAXFIBS;
186 if (rt_numfibs == 0)
187 rt_numfibs = 1;
188 rn_init(); /* initialize all zeroes, all ones, mask table */
189
190#ifndef VIMAGE_GLOBALS
191 vnet_mod_register(&vnet_rtable_modinfo);
192#else
193 vnet_route_iattach(NULL);
194#endif
195}
196
197static int vnet_route_iattach(const void *unused __unused)
198{
199 INIT_VNET_NET(curvnet);
182 int table;
183 struct domain *dom;
200 struct domain *dom;
201 struct radix_node_head **rnh;
202 int table;
184 int fam;
185
203 int fam;
204
205 V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) *
206 sizeof(struct radix_node_head *), M_RTABLE, M_WAITOK|M_ZERO);
207
186 V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
187 NULL, NULL, UMA_ALIGN_PTR, 0);
188 for (dom = domains; dom; dom = dom->dom_next) {
189 if (dom->dom_rtattach) {
190 for (table = 0; table < rt_numfibs; table++) {
191 if ( (fam = dom->dom_family) == AF_INET ||
192 table == 0) {
193 /* for now only AF_INET has > 1 table */
194 /* XXX MRT
195 * rtattach will be also called
196 * from vfs_export.c but the
197 * offset will be 0
198 * (only for AF_INET and AF_INET6
199 * which don't need it anyhow)
200 */
208 V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
209 NULL, NULL, UMA_ALIGN_PTR, 0);
210 for (dom = domains; dom; dom = dom->dom_next) {
211 if (dom->dom_rtattach) {
212 for (table = 0; table < rt_numfibs; table++) {
213 if ( (fam = dom->dom_family) == AF_INET ||
214 table == 0) {
215 /* for now only AF_INET has > 1 table */
216 /* XXX MRT
217 * rtattach will be also called
218 * from vfs_export.c but the
219 * offset will be 0
220 * (only for AF_INET and AF_INET6
221 * which don't need it anyhow)
222 */
201 dom->dom_rtattach(
202 (void **)&V_rt_tables[table][fam],
223 rnh = rt_tables_get_rnh_ptr(table, fam);
224 if (rnh == NULL)
225 panic("%s: rnh NULL", __func__);
226 dom->dom_rtattach((void **)rnh,
203 dom->dom_rtoffset);
204 } else {
205 break;
206 }
207 }
208 }
209 }
210
211 return (0);
212}
213
214#ifndef _SYS_SYSPROTO_H_
215struct setfib_args {
216 int fibnum;
217};
218#endif
219int
220setfib(struct thread *td, struct setfib_args *uap)
221{
222 if (uap->fibnum < 0 || uap->fibnum >= rt_numfibs)
223 return EINVAL;
224 td->td_proc->p_fibnum = uap->fibnum;
225 return (0);
226}
227
228/*
229 * Packet routing routines.
230 */
231void
232rtalloc(struct route *ro)
233{
234 rtalloc_ign_fib(ro, 0UL, 0);
235}
236
237void
238rtalloc_fib(struct route *ro, u_int fibnum)
239{
240 rtalloc_ign_fib(ro, 0UL, fibnum);
241}
242
243void
244rtalloc_ign(struct route *ro, u_long ignore)
245{
246 struct rtentry *rt;
247
248 if ((rt = ro->ro_rt) != NULL) {
249 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
250 return;
251 RTFREE(rt);
252 ro->ro_rt = NULL;
253 }
254 ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, 0);
255 if (ro->ro_rt)
256 RT_UNLOCK(ro->ro_rt);
257}
258
259void
260rtalloc_ign_fib(struct route *ro, u_long ignore, u_int fibnum)
261{
262 struct rtentry *rt;
263
264 if ((rt = ro->ro_rt) != NULL) {
265 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
266 return;
267 RTFREE(rt);
268 ro->ro_rt = NULL;
269 }
270 ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, fibnum);
271 if (ro->ro_rt)
272 RT_UNLOCK(ro->ro_rt);
273}
274
275/*
276 * Look up the route that matches the address given
277 * Or, at least try.. Create a cloned route if needed.
278 *
279 * The returned route, if any, is locked.
280 */
281struct rtentry *
282rtalloc1(struct sockaddr *dst, int report, u_long ignflags)
283{
284 return (rtalloc1_fib(dst, report, ignflags, 0));
285}
286
287struct rtentry *
288rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
289 u_int fibnum)
290{
291 INIT_VNET_NET(curvnet);
292 struct radix_node_head *rnh;
293 struct rtentry *rt;
294 struct radix_node *rn;
295 struct rtentry *newrt;
296 struct rt_addrinfo info;
297 int err = 0, msgtype = RTM_MISS;
298 int needlock;
299
300 KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
301 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
302 fibnum = 0;
227 dom->dom_rtoffset);
228 } else {
229 break;
230 }
231 }
232 }
233 }
234
235 return (0);
236}
237
238#ifndef _SYS_SYSPROTO_H_
239struct setfib_args {
240 int fibnum;
241};
242#endif
243int
244setfib(struct thread *td, struct setfib_args *uap)
245{
246 if (uap->fibnum < 0 || uap->fibnum >= rt_numfibs)
247 return EINVAL;
248 td->td_proc->p_fibnum = uap->fibnum;
249 return (0);
250}
251
252/*
253 * Packet routing routines.
254 */
255void
256rtalloc(struct route *ro)
257{
258 rtalloc_ign_fib(ro, 0UL, 0);
259}
260
261void
262rtalloc_fib(struct route *ro, u_int fibnum)
263{
264 rtalloc_ign_fib(ro, 0UL, fibnum);
265}
266
267void
268rtalloc_ign(struct route *ro, u_long ignore)
269{
270 struct rtentry *rt;
271
272 if ((rt = ro->ro_rt) != NULL) {
273 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
274 return;
275 RTFREE(rt);
276 ro->ro_rt = NULL;
277 }
278 ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, 0);
279 if (ro->ro_rt)
280 RT_UNLOCK(ro->ro_rt);
281}
282
283void
284rtalloc_ign_fib(struct route *ro, u_long ignore, u_int fibnum)
285{
286 struct rtentry *rt;
287
288 if ((rt = ro->ro_rt) != NULL) {
289 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
290 return;
291 RTFREE(rt);
292 ro->ro_rt = NULL;
293 }
294 ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, fibnum);
295 if (ro->ro_rt)
296 RT_UNLOCK(ro->ro_rt);
297}
298
299/*
300 * Look up the route that matches the address given
301 * Or, at least try.. Create a cloned route if needed.
302 *
303 * The returned route, if any, is locked.
304 */
305struct rtentry *
306rtalloc1(struct sockaddr *dst, int report, u_long ignflags)
307{
308 return (rtalloc1_fib(dst, report, ignflags, 0));
309}
310
311struct rtentry *
312rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
313 u_int fibnum)
314{
315 INIT_VNET_NET(curvnet);
316 struct radix_node_head *rnh;
317 struct rtentry *rt;
318 struct radix_node *rn;
319 struct rtentry *newrt;
320 struct rt_addrinfo info;
321 int err = 0, msgtype = RTM_MISS;
322 int needlock;
323
324 KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
325 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
326 fibnum = 0;
303 rnh = V_rt_tables[fibnum][dst->sa_family];
327 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
304 newrt = NULL;
305 /*
306 * Look up the address in the table for that Address Family
307 */
308 if (rnh == NULL) {
309 V_rtstat.rts_unreach++;
310 goto miss;
311 }
312 needlock = !(ignflags & RTF_RNH_LOCKED);
313 if (needlock)
314 RADIX_NODE_HEAD_RLOCK(rnh);
315#ifdef INVARIANTS
316 else
317 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
318#endif
319 rn = rnh->rnh_matchaddr(dst, rnh);
320 if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
321 newrt = rt = RNTORT(rn);
322 RT_LOCK(newrt);
323 RT_ADDREF(newrt);
324 if (needlock)
325 RADIX_NODE_HEAD_RUNLOCK(rnh);
326 goto done;
327
328 } else if (needlock)
329 RADIX_NODE_HEAD_RUNLOCK(rnh);
330
331 /*
332 * Either we hit the root or couldn't find any match,
333 * Which basically means
334 * "caint get there frm here"
335 */
336 V_rtstat.rts_unreach++;
337miss:
338 if (report) {
339 /*
340 * If required, report the failure to the supervising
341 * Authorities.
342 * For a delete, this is not an error. (report == 0)
343 */
344 bzero(&info, sizeof(info));
345 info.rti_info[RTAX_DST] = dst;
346 rt_missmsg(msgtype, &info, 0, err);
347 }
348done:
349 if (newrt)
350 RT_LOCK_ASSERT(newrt);
351 return (newrt);
352}
353
354/*
355 * Remove a reference count from an rtentry.
356 * If the count gets low enough, take it out of the routing table
357 */
358void
359rtfree(struct rtentry *rt)
360{
361 INIT_VNET_NET(curvnet);
362 struct radix_node_head *rnh;
363
364 KASSERT(rt != NULL,("%s: NULL rt", __func__));
328 newrt = NULL;
329 /*
330 * Look up the address in the table for that Address Family
331 */
332 if (rnh == NULL) {
333 V_rtstat.rts_unreach++;
334 goto miss;
335 }
336 needlock = !(ignflags & RTF_RNH_LOCKED);
337 if (needlock)
338 RADIX_NODE_HEAD_RLOCK(rnh);
339#ifdef INVARIANTS
340 else
341 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
342#endif
343 rn = rnh->rnh_matchaddr(dst, rnh);
344 if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
345 newrt = rt = RNTORT(rn);
346 RT_LOCK(newrt);
347 RT_ADDREF(newrt);
348 if (needlock)
349 RADIX_NODE_HEAD_RUNLOCK(rnh);
350 goto done;
351
352 } else if (needlock)
353 RADIX_NODE_HEAD_RUNLOCK(rnh);
354
355 /*
356 * Either we hit the root or couldn't find any match,
357 * Which basically means
358 * "caint get there frm here"
359 */
360 V_rtstat.rts_unreach++;
361miss:
362 if (report) {
363 /*
364 * If required, report the failure to the supervising
365 * Authorities.
366 * For a delete, this is not an error. (report == 0)
367 */
368 bzero(&info, sizeof(info));
369 info.rti_info[RTAX_DST] = dst;
370 rt_missmsg(msgtype, &info, 0, err);
371 }
372done:
373 if (newrt)
374 RT_LOCK_ASSERT(newrt);
375 return (newrt);
376}
377
378/*
379 * Remove a reference count from an rtentry.
380 * If the count gets low enough, take it out of the routing table
381 */
382void
383rtfree(struct rtentry *rt)
384{
385 INIT_VNET_NET(curvnet);
386 struct radix_node_head *rnh;
387
388 KASSERT(rt != NULL,("%s: NULL rt", __func__));
365 rnh = V_rt_tables[rt->rt_fibnum][rt_key(rt)->sa_family];
389 rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
366 KASSERT(rnh != NULL,("%s: NULL rnh", __func__));
367
368 RT_LOCK_ASSERT(rt);
369
370 /*
371 * The callers should use RTFREE_LOCKED() or RTFREE(), so
372 * we should come here exactly with the last reference.
373 */
374 RT_REMREF(rt);
375 if (rt->rt_refcnt > 0) {
376 log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt);
377 goto done;
378 }
379
380 /*
381 * On last reference give the "close method" a chance
382 * to cleanup private state. This also permits (for
383 * IPv4 and IPv6) a chance to decide if the routing table
384 * entry should be purged immediately or at a later time.
385 * When an immediate purge is to happen the close routine
386 * typically calls rtexpunge which clears the RTF_UP flag
387 * on the entry so that the code below reclaims the storage.
388 */
389 if (rt->rt_refcnt == 0 && rnh->rnh_close)
390 rnh->rnh_close((struct radix_node *)rt, rnh);
391
392 /*
393 * If we are no longer "up" (and ref == 0)
394 * then we can free the resources associated
395 * with the route.
396 */
397 if ((rt->rt_flags & RTF_UP) == 0) {
398 if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
399 panic("rtfree 2");
400 /*
401 * the rtentry must have been removed from the routing table
402 * so it is represented in rttrash.. remove that now.
403 */
404 V_rttrash--;
405#ifdef DIAGNOSTIC
406 if (rt->rt_refcnt < 0) {
407 printf("rtfree: %p not freed (neg refs)\n", rt);
408 goto done;
409 }
410#endif
411 /*
412 * release references on items we hold them on..
413 * e.g other routes and ifaddrs.
414 */
415 if (rt->rt_ifa)
416 IFAFREE(rt->rt_ifa);
417 /*
418 * The key is separatly alloc'd so free it (see rt_setgate()).
419 * This also frees the gateway, as they are always malloc'd
420 * together.
421 */
422 Free(rt_key(rt));
423
424 /*
425 * and the rtentry itself of course
426 */
427 RT_LOCK_DESTROY(rt);
428 uma_zfree(V_rtzone, rt);
429 return;
430 }
431done:
432 RT_UNLOCK(rt);
433}
434
435
436/*
437 * Force a routing table entry to the specified
438 * destination to go through the given gateway.
439 * Normally called as a result of a routing redirect
440 * message from the network layer.
441 */
442void
443rtredirect(struct sockaddr *dst,
444 struct sockaddr *gateway,
445 struct sockaddr *netmask,
446 int flags,
447 struct sockaddr *src)
448{
449 rtredirect_fib(dst, gateway, netmask, flags, src, 0);
450}
451
452void
453rtredirect_fib(struct sockaddr *dst,
454 struct sockaddr *gateway,
455 struct sockaddr *netmask,
456 int flags,
457 struct sockaddr *src,
458 u_int fibnum)
459{
460 INIT_VNET_NET(curvnet);
461 struct rtentry *rt, *rt0 = NULL;
462 int error = 0;
463 short *stat = NULL;
464 struct rt_addrinfo info;
465 struct ifaddr *ifa;
390 KASSERT(rnh != NULL,("%s: NULL rnh", __func__));
391
392 RT_LOCK_ASSERT(rt);
393
394 /*
395 * The callers should use RTFREE_LOCKED() or RTFREE(), so
396 * we should come here exactly with the last reference.
397 */
398 RT_REMREF(rt);
399 if (rt->rt_refcnt > 0) {
400 log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt);
401 goto done;
402 }
403
404 /*
405 * On last reference give the "close method" a chance
406 * to cleanup private state. This also permits (for
407 * IPv4 and IPv6) a chance to decide if the routing table
408 * entry should be purged immediately or at a later time.
409 * When an immediate purge is to happen the close routine
410 * typically calls rtexpunge which clears the RTF_UP flag
411 * on the entry so that the code below reclaims the storage.
412 */
413 if (rt->rt_refcnt == 0 && rnh->rnh_close)
414 rnh->rnh_close((struct radix_node *)rt, rnh);
415
416 /*
417 * If we are no longer "up" (and ref == 0)
418 * then we can free the resources associated
419 * with the route.
420 */
421 if ((rt->rt_flags & RTF_UP) == 0) {
422 if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
423 panic("rtfree 2");
424 /*
425 * the rtentry must have been removed from the routing table
426 * so it is represented in rttrash.. remove that now.
427 */
428 V_rttrash--;
429#ifdef DIAGNOSTIC
430 if (rt->rt_refcnt < 0) {
431 printf("rtfree: %p not freed (neg refs)\n", rt);
432 goto done;
433 }
434#endif
435 /*
436 * release references on items we hold them on..
437 * e.g other routes and ifaddrs.
438 */
439 if (rt->rt_ifa)
440 IFAFREE(rt->rt_ifa);
441 /*
442 * The key is separatly alloc'd so free it (see rt_setgate()).
443 * This also frees the gateway, as they are always malloc'd
444 * together.
445 */
446 Free(rt_key(rt));
447
448 /*
449 * and the rtentry itself of course
450 */
451 RT_LOCK_DESTROY(rt);
452 uma_zfree(V_rtzone, rt);
453 return;
454 }
455done:
456 RT_UNLOCK(rt);
457}
458
459
460/*
461 * Force a routing table entry to the specified
462 * destination to go through the given gateway.
463 * Normally called as a result of a routing redirect
464 * message from the network layer.
465 */
466void
467rtredirect(struct sockaddr *dst,
468 struct sockaddr *gateway,
469 struct sockaddr *netmask,
470 int flags,
471 struct sockaddr *src)
472{
473 rtredirect_fib(dst, gateway, netmask, flags, src, 0);
474}
475
476void
477rtredirect_fib(struct sockaddr *dst,
478 struct sockaddr *gateway,
479 struct sockaddr *netmask,
480 int flags,
481 struct sockaddr *src,
482 u_int fibnum)
483{
484 INIT_VNET_NET(curvnet);
485 struct rtentry *rt, *rt0 = NULL;
486 int error = 0;
487 short *stat = NULL;
488 struct rt_addrinfo info;
489 struct ifaddr *ifa;
466 struct radix_node_head *rnh =
467 V_rt_tables[fibnum][dst->sa_family];
490 struct radix_node_head *rnh;
468
491
492 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
493 if (rnh == NULL) {
494 error = EAFNOSUPPORT;
495 goto out;
496 }
497
469 /* verify the gateway is directly reachable */
470 if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
471 error = ENETUNREACH;
472 goto out;
473 }
474 rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
475 /*
476 * If the redirect isn't from our current router for this dst,
477 * it's either old or wrong. If it redirects us to ourselves,
478 * we have a routing loop, perhaps as a result of an interface
479 * going down recently.
480 */
481 if (!(flags & RTF_DONE) && rt &&
482 (!sa_equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
483 error = EINVAL;
484 else if (ifa_ifwithaddr(gateway))
485 error = EHOSTUNREACH;
486 if (error)
487 goto done;
488 /*
489 * Create a new entry if we just got back a wildcard entry
490 * or the the lookup failed. This is necessary for hosts
491 * which use routing redirects generated by smart gateways
492 * to dynamically build the routing tables.
493 */
494 if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
495 goto create;
496 /*
497 * Don't listen to the redirect if it's
498 * for a route to an interface.
499 */
500 if (rt->rt_flags & RTF_GATEWAY) {
501 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
502 /*
503 * Changing from route to net => route to host.
504 * Create new route, rather than smashing route to net.
505 */
506 create:
507 rt0 = rt;
508 rt = NULL;
509
510 flags |= RTF_GATEWAY | RTF_DYNAMIC;
511 bzero((caddr_t)&info, sizeof(info));
512 info.rti_info[RTAX_DST] = dst;
513 info.rti_info[RTAX_GATEWAY] = gateway;
514 info.rti_info[RTAX_NETMASK] = netmask;
515 info.rti_ifa = ifa;
516 info.rti_flags = flags;
517 if (rt0 != NULL)
518 RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */
519 error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
520 if (rt != NULL) {
521 RT_LOCK(rt);
522 if (rt0 != NULL)
523 EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
524 flags = rt->rt_flags;
525 }
526 if (rt0 != NULL)
527 RTFREE(rt0);
528
529 stat = &V_rtstat.rts_dynamic;
530 } else {
531 struct rtentry *gwrt;
532
533 /*
534 * Smash the current notion of the gateway to
535 * this destination. Should check about netmask!!!
536 */
537 rt->rt_flags |= RTF_MODIFIED;
538 flags |= RTF_MODIFIED;
539 stat = &V_rtstat.rts_newgateway;
540 /*
541 * add the key and gateway (in one malloc'd chunk).
542 */
543 RT_UNLOCK(rt);
544 RADIX_NODE_HEAD_LOCK(rnh);
545 RT_LOCK(rt);
546 rt_setgate(rt, rt_key(rt), gateway);
547 gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
548 RADIX_NODE_HEAD_UNLOCK(rnh);
549 EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
550 RTFREE_LOCKED(gwrt);
551 }
552 } else
553 error = EHOSTUNREACH;
554done:
555 if (rt)
556 RTFREE_LOCKED(rt);
557out:
558 if (error)
559 V_rtstat.rts_badredirect++;
560 else if (stat != NULL)
561 (*stat)++;
562 bzero((caddr_t)&info, sizeof(info));
563 info.rti_info[RTAX_DST] = dst;
564 info.rti_info[RTAX_GATEWAY] = gateway;
565 info.rti_info[RTAX_NETMASK] = netmask;
566 info.rti_info[RTAX_AUTHOR] = src;
567 rt_missmsg(RTM_REDIRECT, &info, flags, error);
568}
569
570int
571rtioctl(u_long req, caddr_t data)
572{
573 return (rtioctl_fib(req, data, 0));
574}
575
576/*
577 * Routing table ioctl interface.
578 */
579int
580rtioctl_fib(u_long req, caddr_t data, u_int fibnum)
581{
582
583 /*
584 * If more ioctl commands are added here, make sure the proper
585 * super-user checks are being performed because it is possible for
586 * prison-root to make it this far if raw sockets have been enabled
587 * in jails.
588 */
589#ifdef INET
590 /* Multicast goop, grrr... */
591 return mrt_ioctl ? mrt_ioctl(req, data, fibnum) : EOPNOTSUPP;
592#else /* INET */
593 return ENXIO;
594#endif /* INET */
595}
596
597struct ifaddr *
598ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
599{
600 return (ifa_ifwithroute_fib(flags, dst, gateway, 0));
601}
602
603struct ifaddr *
604ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway,
605 u_int fibnum)
606{
607 register struct ifaddr *ifa;
608 int not_found = 0;
609
610 if ((flags & RTF_GATEWAY) == 0) {
611 /*
612 * If we are adding a route to an interface,
613 * and the interface is a pt to pt link
614 * we should search for the destination
615 * as our clue to the interface. Otherwise
616 * we can use the local address.
617 */
618 ifa = NULL;
619 if (flags & RTF_HOST)
620 ifa = ifa_ifwithdstaddr(dst);
621 if (ifa == NULL)
622 ifa = ifa_ifwithaddr(gateway);
623 } else {
624 /*
625 * If we are adding a route to a remote net
626 * or host, the gateway may still be on the
627 * other end of a pt to pt link.
628 */
629 ifa = ifa_ifwithdstaddr(gateway);
630 }
631 if (ifa == NULL)
632 ifa = ifa_ifwithnet(gateway);
633 if (ifa == NULL) {
634 struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
635 if (rt == NULL)
636 return (NULL);
637 /*
638 * dismiss a gateway that is reachable only
639 * through the default router
640 */
641 switch (gateway->sa_family) {
642 case AF_INET:
643 if (satosin(rt_key(rt))->sin_addr.s_addr == INADDR_ANY)
644 not_found = 1;
645 break;
646 case AF_INET6:
647 if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(rt))->sin6_addr))
648 not_found = 1;
649 break;
650 default:
651 break;
652 }
653 RT_REMREF(rt);
654 RT_UNLOCK(rt);
655 if (not_found)
656 return (NULL);
657 if ((ifa = rt->rt_ifa) == NULL)
658 return (NULL);
659 }
660 if (ifa->ifa_addr->sa_family != dst->sa_family) {
661 struct ifaddr *oifa = ifa;
662 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
663 if (ifa == NULL)
664 ifa = oifa;
665 }
666 return (ifa);
667}
668
669/*
670 * Do appropriate manipulations of a routing tree given
671 * all the bits of info needed
672 */
673int
674rtrequest(int req,
675 struct sockaddr *dst,
676 struct sockaddr *gateway,
677 struct sockaddr *netmask,
678 int flags,
679 struct rtentry **ret_nrt)
680{
681 return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt, 0));
682}
683
684int
685rtrequest_fib(int req,
686 struct sockaddr *dst,
687 struct sockaddr *gateway,
688 struct sockaddr *netmask,
689 int flags,
690 struct rtentry **ret_nrt,
691 u_int fibnum)
692{
693 struct rt_addrinfo info;
694
695 if (dst->sa_len == 0)
696 return(EINVAL);
697
698 bzero((caddr_t)&info, sizeof(info));
699 info.rti_flags = flags;
700 info.rti_info[RTAX_DST] = dst;
701 info.rti_info[RTAX_GATEWAY] = gateway;
702 info.rti_info[RTAX_NETMASK] = netmask;
703 return rtrequest1_fib(req, &info, ret_nrt, fibnum);
704}
705
706/*
707 * These (questionable) definitions of apparent local variables apply
708 * to the next two functions. XXXXXX!!!
709 */
710#define dst info->rti_info[RTAX_DST]
711#define gateway info->rti_info[RTAX_GATEWAY]
712#define netmask info->rti_info[RTAX_NETMASK]
713#define ifaaddr info->rti_info[RTAX_IFA]
714#define ifpaddr info->rti_info[RTAX_IFP]
715#define flags info->rti_flags
716
717int
718rt_getifa(struct rt_addrinfo *info)
719{
720 return (rt_getifa_fib(info, 0));
721}
722
723int
724rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
725{
726 struct ifaddr *ifa;
727 int error = 0;
728
729 /*
730 * ifp may be specified by sockaddr_dl
731 * when protocol address is ambiguous.
732 */
733 if (info->rti_ifp == NULL && ifpaddr != NULL &&
734 ifpaddr->sa_family == AF_LINK &&
735 (ifa = ifa_ifwithnet(ifpaddr)) != NULL)
736 info->rti_ifp = ifa->ifa_ifp;
737 if (info->rti_ifa == NULL && ifaaddr != NULL)
738 info->rti_ifa = ifa_ifwithaddr(ifaaddr);
739 if (info->rti_ifa == NULL) {
740 struct sockaddr *sa;
741
742 sa = ifaaddr != NULL ? ifaaddr :
743 (gateway != NULL ? gateway : dst);
744 if (sa != NULL && info->rti_ifp != NULL)
745 info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp);
746 else if (dst != NULL && gateway != NULL)
747 info->rti_ifa = ifa_ifwithroute_fib(flags, dst, gateway,
748 fibnum);
749 else if (sa != NULL)
750 info->rti_ifa = ifa_ifwithroute_fib(flags, sa, sa,
751 fibnum);
752 }
753 if ((ifa = info->rti_ifa) != NULL) {
754 if (info->rti_ifp == NULL)
755 info->rti_ifp = ifa->ifa_ifp;
756 } else
757 error = ENETUNREACH;
758 return (error);
759}
760
761/*
762 * Expunges references to a route that's about to be reclaimed.
763 * The route must be locked.
764 */
765int
766rtexpunge(struct rtentry *rt)
767{
768 INIT_VNET_NET(curvnet);
769 struct radix_node *rn;
770 struct radix_node_head *rnh;
771 struct ifaddr *ifa;
772 int error = 0;
773
774 /*
775 * Find the correct routing tree to use for this Address Family
776 */
498 /* verify the gateway is directly reachable */
499 if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
500 error = ENETUNREACH;
501 goto out;
502 }
503 rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
504 /*
505 * If the redirect isn't from our current router for this dst,
506 * it's either old or wrong. If it redirects us to ourselves,
507 * we have a routing loop, perhaps as a result of an interface
508 * going down recently.
509 */
510 if (!(flags & RTF_DONE) && rt &&
511 (!sa_equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
512 error = EINVAL;
513 else if (ifa_ifwithaddr(gateway))
514 error = EHOSTUNREACH;
515 if (error)
516 goto done;
517 /*
518 * Create a new entry if we just got back a wildcard entry
519 * or the the lookup failed. This is necessary for hosts
520 * which use routing redirects generated by smart gateways
521 * to dynamically build the routing tables.
522 */
523 if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
524 goto create;
525 /*
526 * Don't listen to the redirect if it's
527 * for a route to an interface.
528 */
529 if (rt->rt_flags & RTF_GATEWAY) {
530 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
531 /*
532 * Changing from route to net => route to host.
533 * Create new route, rather than smashing route to net.
534 */
535 create:
536 rt0 = rt;
537 rt = NULL;
538
539 flags |= RTF_GATEWAY | RTF_DYNAMIC;
540 bzero((caddr_t)&info, sizeof(info));
541 info.rti_info[RTAX_DST] = dst;
542 info.rti_info[RTAX_GATEWAY] = gateway;
543 info.rti_info[RTAX_NETMASK] = netmask;
544 info.rti_ifa = ifa;
545 info.rti_flags = flags;
546 if (rt0 != NULL)
547 RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */
548 error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
549 if (rt != NULL) {
550 RT_LOCK(rt);
551 if (rt0 != NULL)
552 EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
553 flags = rt->rt_flags;
554 }
555 if (rt0 != NULL)
556 RTFREE(rt0);
557
558 stat = &V_rtstat.rts_dynamic;
559 } else {
560 struct rtentry *gwrt;
561
562 /*
563 * Smash the current notion of the gateway to
564 * this destination. Should check about netmask!!!
565 */
566 rt->rt_flags |= RTF_MODIFIED;
567 flags |= RTF_MODIFIED;
568 stat = &V_rtstat.rts_newgateway;
569 /*
570 * add the key and gateway (in one malloc'd chunk).
571 */
572 RT_UNLOCK(rt);
573 RADIX_NODE_HEAD_LOCK(rnh);
574 RT_LOCK(rt);
575 rt_setgate(rt, rt_key(rt), gateway);
576 gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
577 RADIX_NODE_HEAD_UNLOCK(rnh);
578 EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
579 RTFREE_LOCKED(gwrt);
580 }
581 } else
582 error = EHOSTUNREACH;
583done:
584 if (rt)
585 RTFREE_LOCKED(rt);
586out:
587 if (error)
588 V_rtstat.rts_badredirect++;
589 else if (stat != NULL)
590 (*stat)++;
591 bzero((caddr_t)&info, sizeof(info));
592 info.rti_info[RTAX_DST] = dst;
593 info.rti_info[RTAX_GATEWAY] = gateway;
594 info.rti_info[RTAX_NETMASK] = netmask;
595 info.rti_info[RTAX_AUTHOR] = src;
596 rt_missmsg(RTM_REDIRECT, &info, flags, error);
597}
598
599int
600rtioctl(u_long req, caddr_t data)
601{
602 return (rtioctl_fib(req, data, 0));
603}
604
605/*
606 * Routing table ioctl interface.
607 */
608int
609rtioctl_fib(u_long req, caddr_t data, u_int fibnum)
610{
611
612 /*
613 * If more ioctl commands are added here, make sure the proper
614 * super-user checks are being performed because it is possible for
615 * prison-root to make it this far if raw sockets have been enabled
616 * in jails.
617 */
618#ifdef INET
619 /* Multicast goop, grrr... */
620 return mrt_ioctl ? mrt_ioctl(req, data, fibnum) : EOPNOTSUPP;
621#else /* INET */
622 return ENXIO;
623#endif /* INET */
624}
625
626struct ifaddr *
627ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
628{
629 return (ifa_ifwithroute_fib(flags, dst, gateway, 0));
630}
631
632struct ifaddr *
633ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway,
634 u_int fibnum)
635{
636 register struct ifaddr *ifa;
637 int not_found = 0;
638
639 if ((flags & RTF_GATEWAY) == 0) {
640 /*
641 * If we are adding a route to an interface,
642 * and the interface is a pt to pt link
643 * we should search for the destination
644 * as our clue to the interface. Otherwise
645 * we can use the local address.
646 */
647 ifa = NULL;
648 if (flags & RTF_HOST)
649 ifa = ifa_ifwithdstaddr(dst);
650 if (ifa == NULL)
651 ifa = ifa_ifwithaddr(gateway);
652 } else {
653 /*
654 * If we are adding a route to a remote net
655 * or host, the gateway may still be on the
656 * other end of a pt to pt link.
657 */
658 ifa = ifa_ifwithdstaddr(gateway);
659 }
660 if (ifa == NULL)
661 ifa = ifa_ifwithnet(gateway);
662 if (ifa == NULL) {
663 struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
664 if (rt == NULL)
665 return (NULL);
666 /*
667 * dismiss a gateway that is reachable only
668 * through the default router
669 */
670 switch (gateway->sa_family) {
671 case AF_INET:
672 if (satosin(rt_key(rt))->sin_addr.s_addr == INADDR_ANY)
673 not_found = 1;
674 break;
675 case AF_INET6:
676 if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(rt))->sin6_addr))
677 not_found = 1;
678 break;
679 default:
680 break;
681 }
682 RT_REMREF(rt);
683 RT_UNLOCK(rt);
684 if (not_found)
685 return (NULL);
686 if ((ifa = rt->rt_ifa) == NULL)
687 return (NULL);
688 }
689 if (ifa->ifa_addr->sa_family != dst->sa_family) {
690 struct ifaddr *oifa = ifa;
691 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
692 if (ifa == NULL)
693 ifa = oifa;
694 }
695 return (ifa);
696}
697
698/*
699 * Do appropriate manipulations of a routing tree given
700 * all the bits of info needed
701 */
702int
703rtrequest(int req,
704 struct sockaddr *dst,
705 struct sockaddr *gateway,
706 struct sockaddr *netmask,
707 int flags,
708 struct rtentry **ret_nrt)
709{
710 return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt, 0));
711}
712
713int
714rtrequest_fib(int req,
715 struct sockaddr *dst,
716 struct sockaddr *gateway,
717 struct sockaddr *netmask,
718 int flags,
719 struct rtentry **ret_nrt,
720 u_int fibnum)
721{
722 struct rt_addrinfo info;
723
724 if (dst->sa_len == 0)
725 return(EINVAL);
726
727 bzero((caddr_t)&info, sizeof(info));
728 info.rti_flags = flags;
729 info.rti_info[RTAX_DST] = dst;
730 info.rti_info[RTAX_GATEWAY] = gateway;
731 info.rti_info[RTAX_NETMASK] = netmask;
732 return rtrequest1_fib(req, &info, ret_nrt, fibnum);
733}
734
735/*
736 * These (questionable) definitions of apparent local variables apply
737 * to the next two functions. XXXXXX!!!
738 */
739#define dst info->rti_info[RTAX_DST]
740#define gateway info->rti_info[RTAX_GATEWAY]
741#define netmask info->rti_info[RTAX_NETMASK]
742#define ifaaddr info->rti_info[RTAX_IFA]
743#define ifpaddr info->rti_info[RTAX_IFP]
744#define flags info->rti_flags
745
746int
747rt_getifa(struct rt_addrinfo *info)
748{
749 return (rt_getifa_fib(info, 0));
750}
751
752int
753rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
754{
755 struct ifaddr *ifa;
756 int error = 0;
757
758 /*
759 * ifp may be specified by sockaddr_dl
760 * when protocol address is ambiguous.
761 */
762 if (info->rti_ifp == NULL && ifpaddr != NULL &&
763 ifpaddr->sa_family == AF_LINK &&
764 (ifa = ifa_ifwithnet(ifpaddr)) != NULL)
765 info->rti_ifp = ifa->ifa_ifp;
766 if (info->rti_ifa == NULL && ifaaddr != NULL)
767 info->rti_ifa = ifa_ifwithaddr(ifaaddr);
768 if (info->rti_ifa == NULL) {
769 struct sockaddr *sa;
770
771 sa = ifaaddr != NULL ? ifaaddr :
772 (gateway != NULL ? gateway : dst);
773 if (sa != NULL && info->rti_ifp != NULL)
774 info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp);
775 else if (dst != NULL && gateway != NULL)
776 info->rti_ifa = ifa_ifwithroute_fib(flags, dst, gateway,
777 fibnum);
778 else if (sa != NULL)
779 info->rti_ifa = ifa_ifwithroute_fib(flags, sa, sa,
780 fibnum);
781 }
782 if ((ifa = info->rti_ifa) != NULL) {
783 if (info->rti_ifp == NULL)
784 info->rti_ifp = ifa->ifa_ifp;
785 } else
786 error = ENETUNREACH;
787 return (error);
788}
789
790/*
791 * Expunges references to a route that's about to be reclaimed.
792 * The route must be locked.
793 */
794int
795rtexpunge(struct rtentry *rt)
796{
797 INIT_VNET_NET(curvnet);
798 struct radix_node *rn;
799 struct radix_node_head *rnh;
800 struct ifaddr *ifa;
801 int error = 0;
802
803 /*
804 * Find the correct routing tree to use for this Address Family
805 */
777 rnh = V_rt_tables[rt->rt_fibnum][rt_key(rt)->sa_family];
806 rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
778 RT_LOCK_ASSERT(rt);
779 if (rnh == NULL)
780 return (EAFNOSUPPORT);
781 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
782#if 0
783 /*
784 * We cannot assume anything about the reference count
785 * because protocols call us in many situations; often
786 * before unwinding references to the table entry.
787 */
788 KASSERT(rt->rt_refcnt <= 1, ("bogus refcnt %ld", rt->rt_refcnt));
789#endif
790 /*
791 * Remove the item from the tree; it should be there,
792 * but when callers invoke us blindly it may not (sigh).
793 */
794 rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh);
795 if (rn == NULL) {
796 error = ESRCH;
797 goto bad;
798 }
799 KASSERT((rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) == 0,
800 ("unexpected flags 0x%x", rn->rn_flags));
801 KASSERT(rt == RNTORT(rn),
802 ("lookup mismatch, rt %p rn %p", rt, rn));
803
804 rt->rt_flags &= ~RTF_UP;
805
806 /*
807 * Give the protocol a chance to keep things in sync.
808 */
809 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) {
810 struct rt_addrinfo info;
811
812 bzero((caddr_t)&info, sizeof(info));
813 info.rti_flags = rt->rt_flags;
814 info.rti_info[RTAX_DST] = rt_key(rt);
815 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
816 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
817 ifa->ifa_rtrequest(RTM_DELETE, rt, &info);
818 }
819
820 /*
821 * one more rtentry floating around that is not
822 * linked to the routing table.
823 */
824 V_rttrash++;
825bad:
826 return (error);
827}
828
829#ifdef RADIX_MPATH
830static int
831rn_mpath_update(int req, struct rt_addrinfo *info,
832 struct radix_node_head *rnh, struct rtentry **ret_nrt)
833{
834 /*
835 * if we got multipath routes, we require users to specify
836 * a matching RTAX_GATEWAY.
837 */
838 struct rtentry *rt, *rto = NULL;
839 register struct radix_node *rn;
840 int error = 0;
841
842 rn = rnh->rnh_matchaddr(dst, rnh);
843 if (rn == NULL)
844 return (ESRCH);
845 rto = rt = RNTORT(rn);
846 rt = rt_mpath_matchgate(rt, gateway);
847 if (rt == NULL)
848 return (ESRCH);
849 /*
850 * this is the first entry in the chain
851 */
852 if (rto == rt) {
853 rn = rn_mpath_next((struct radix_node *)rt);
854 /*
855 * there is another entry, now it's active
856 */
857 if (rn) {
858 rto = RNTORT(rn);
859 RT_LOCK(rto);
860 rto->rt_flags |= RTF_UP;
861 RT_UNLOCK(rto);
862 } else if (rt->rt_flags & RTF_GATEWAY) {
863 /*
864 * For gateway routes, we need to
865 * make sure that we we are deleting
866 * the correct gateway.
867 * rt_mpath_matchgate() does not
868 * check the case when there is only
869 * one route in the chain.
870 */
871 if (gateway &&
872 (rt->rt_gateway->sa_len != gateway->sa_len ||
873 memcmp(rt->rt_gateway, gateway, gateway->sa_len)))
874 error = ESRCH;
875 goto done;
876 }
877 /*
878 * use the normal delete code to remove
879 * the first entry
880 */
881 if (req != RTM_DELETE)
882 goto nondelete;
883
884 error = ENOENT;
885 goto done;
886 }
887
888 /*
889 * if the entry is 2nd and on up
890 */
891 if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt))
892 panic ("rtrequest1: rt_mpath_deldup");
893 RT_LOCK(rt);
894 RT_ADDREF(rt);
895 if (req == RTM_DELETE) {
896 rt->rt_flags &= ~RTF_UP;
897 /*
898 * One more rtentry floating around that is not
899 * linked to the routing table. rttrash will be decremented
900 * when RTFREE(rt) is eventually called.
901 */
902 V_rttrash++;
903
904 }
905
906nondelete:
907 if (req != RTM_DELETE)
908 panic("unrecognized request %d", req);
909
910
911 /*
912 * If the caller wants it, then it can have it,
913 * but it's up to it to free the rtentry as we won't be
914 * doing it.
915 */
916 if (ret_nrt) {
917 *ret_nrt = rt;
918 RT_UNLOCK(rt);
919 } else
920 RTFREE_LOCKED(rt);
921done:
922 return (error);
923}
924#endif
925
926int
927rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
928 u_int fibnum)
929{
930 INIT_VNET_NET(curvnet);
931 int error = 0, needlock = 0;
932 register struct rtentry *rt;
933 register struct radix_node *rn;
934 register struct radix_node_head *rnh;
935 struct ifaddr *ifa;
936 struct sockaddr *ndst;
937#define senderr(x) { error = x ; goto bad; }
938
939 KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
940 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
941 fibnum = 0;
942 /*
943 * Find the correct routing tree to use for this Address Family
944 */
807 RT_LOCK_ASSERT(rt);
808 if (rnh == NULL)
809 return (EAFNOSUPPORT);
810 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
811#if 0
812 /*
813 * We cannot assume anything about the reference count
814 * because protocols call us in many situations; often
815 * before unwinding references to the table entry.
816 */
817 KASSERT(rt->rt_refcnt <= 1, ("bogus refcnt %ld", rt->rt_refcnt));
818#endif
819 /*
820 * Remove the item from the tree; it should be there,
821 * but when callers invoke us blindly it may not (sigh).
822 */
823 rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh);
824 if (rn == NULL) {
825 error = ESRCH;
826 goto bad;
827 }
828 KASSERT((rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) == 0,
829 ("unexpected flags 0x%x", rn->rn_flags));
830 KASSERT(rt == RNTORT(rn),
831 ("lookup mismatch, rt %p rn %p", rt, rn));
832
833 rt->rt_flags &= ~RTF_UP;
834
835 /*
836 * Give the protocol a chance to keep things in sync.
837 */
838 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) {
839 struct rt_addrinfo info;
840
841 bzero((caddr_t)&info, sizeof(info));
842 info.rti_flags = rt->rt_flags;
843 info.rti_info[RTAX_DST] = rt_key(rt);
844 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
845 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
846 ifa->ifa_rtrequest(RTM_DELETE, rt, &info);
847 }
848
849 /*
850 * one more rtentry floating around that is not
851 * linked to the routing table.
852 */
853 V_rttrash++;
854bad:
855 return (error);
856}
857
858#ifdef RADIX_MPATH
859static int
860rn_mpath_update(int req, struct rt_addrinfo *info,
861 struct radix_node_head *rnh, struct rtentry **ret_nrt)
862{
863 /*
864 * if we got multipath routes, we require users to specify
865 * a matching RTAX_GATEWAY.
866 */
867 struct rtentry *rt, *rto = NULL;
868 register struct radix_node *rn;
869 int error = 0;
870
871 rn = rnh->rnh_matchaddr(dst, rnh);
872 if (rn == NULL)
873 return (ESRCH);
874 rto = rt = RNTORT(rn);
875 rt = rt_mpath_matchgate(rt, gateway);
876 if (rt == NULL)
877 return (ESRCH);
878 /*
879 * this is the first entry in the chain
880 */
881 if (rto == rt) {
882 rn = rn_mpath_next((struct radix_node *)rt);
883 /*
884 * there is another entry, now it's active
885 */
886 if (rn) {
887 rto = RNTORT(rn);
888 RT_LOCK(rto);
889 rto->rt_flags |= RTF_UP;
890 RT_UNLOCK(rto);
891 } else if (rt->rt_flags & RTF_GATEWAY) {
892 /*
893 * For gateway routes, we need to
894 * make sure that we we are deleting
895 * the correct gateway.
896 * rt_mpath_matchgate() does not
897 * check the case when there is only
898 * one route in the chain.
899 */
900 if (gateway &&
901 (rt->rt_gateway->sa_len != gateway->sa_len ||
902 memcmp(rt->rt_gateway, gateway, gateway->sa_len)))
903 error = ESRCH;
904 goto done;
905 }
906 /*
907 * use the normal delete code to remove
908 * the first entry
909 */
910 if (req != RTM_DELETE)
911 goto nondelete;
912
913 error = ENOENT;
914 goto done;
915 }
916
917 /*
918 * if the entry is 2nd and on up
919 */
920 if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt))
921 panic ("rtrequest1: rt_mpath_deldup");
922 RT_LOCK(rt);
923 RT_ADDREF(rt);
924 if (req == RTM_DELETE) {
925 rt->rt_flags &= ~RTF_UP;
926 /*
927 * One more rtentry floating around that is not
928 * linked to the routing table. rttrash will be decremented
929 * when RTFREE(rt) is eventually called.
930 */
931 V_rttrash++;
932
933 }
934
935nondelete:
936 if (req != RTM_DELETE)
937 panic("unrecognized request %d", req);
938
939
940 /*
941 * If the caller wants it, then it can have it,
942 * but it's up to it to free the rtentry as we won't be
943 * doing it.
944 */
945 if (ret_nrt) {
946 *ret_nrt = rt;
947 RT_UNLOCK(rt);
948 } else
949 RTFREE_LOCKED(rt);
950done:
951 return (error);
952}
953#endif
954
955int
956rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
957 u_int fibnum)
958{
959 INIT_VNET_NET(curvnet);
960 int error = 0, needlock = 0;
961 register struct rtentry *rt;
962 register struct radix_node *rn;
963 register struct radix_node_head *rnh;
964 struct ifaddr *ifa;
965 struct sockaddr *ndst;
966#define senderr(x) { error = x ; goto bad; }
967
968 KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
969 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
970 fibnum = 0;
971 /*
972 * Find the correct routing tree to use for this Address Family
973 */
945 rnh = V_rt_tables[fibnum][dst->sa_family];
974 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
946 if (rnh == NULL)
947 return (EAFNOSUPPORT);
948 needlock = ((flags & RTF_RNH_LOCKED) == 0);
949 flags &= ~RTF_RNH_LOCKED;
950 if (needlock)
951 RADIX_NODE_HEAD_LOCK(rnh);
952 else
953 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
954 /*
955 * If we are adding a host route then we don't want to put
956 * a netmask in the tree, nor do we want to clone it.
957 */
958 if (flags & RTF_HOST)
959 netmask = NULL;
960
961 switch (req) {
962 case RTM_DELETE:
963#ifdef RADIX_MPATH
964 if (rn_mpath_capable(rnh)) {
965 error = rn_mpath_update(req, info, rnh, ret_nrt);
966 /*
967 * "bad" holds true for the success case
968 * as well
969 */
970 if (error != ENOENT)
971 goto bad;
972 }
973#endif
974 /*
975 * Remove the item from the tree and return it.
976 * Complain if it is not there and do no more processing.
977 */
978 rn = rnh->rnh_deladdr(dst, netmask, rnh);
979 if (rn == NULL)
980 senderr(ESRCH);
981 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
982 panic ("rtrequest delete");
983 rt = RNTORT(rn);
984 RT_LOCK(rt);
985 RT_ADDREF(rt);
986 rt->rt_flags &= ~RTF_UP;
987
988 /*
989 * give the protocol a chance to keep things in sync.
990 */
991 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
992 ifa->ifa_rtrequest(RTM_DELETE, rt, info);
993
994 /*
995 * One more rtentry floating around that is not
996 * linked to the routing table. rttrash will be decremented
997 * when RTFREE(rt) is eventually called.
998 */
999 V_rttrash++;
1000
1001 /*
1002 * If the caller wants it, then it can have it,
1003 * but it's up to it to free the rtentry as we won't be
1004 * doing it.
1005 */
1006 if (ret_nrt) {
1007 *ret_nrt = rt;
1008 RT_UNLOCK(rt);
1009 } else
1010 RTFREE_LOCKED(rt);
1011 break;
1012 case RTM_RESOLVE:
1013 /*
1014 * resolve was only used for route cloning
1015 * here for compat
1016 */
1017 break;
1018 case RTM_ADD:
1019 if ((flags & RTF_GATEWAY) && !gateway)
1020 senderr(EINVAL);
1021 if (dst && gateway && (dst->sa_family != gateway->sa_family) &&
1022 (gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK))
1023 senderr(EINVAL);
1024
1025 if (info->rti_ifa == NULL && (error = rt_getifa_fib(info, fibnum)))
1026 senderr(error);
1027 ifa = info->rti_ifa;
1028 rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
1029 if (rt == NULL)
1030 senderr(ENOBUFS);
1031 RT_LOCK_INIT(rt);
1032 rt->rt_flags = RTF_UP | flags;
1033 rt->rt_fibnum = fibnum;
1034 /*
1035 * Add the gateway. Possibly re-malloc-ing the storage for it
1036 *
1037 */
1038 RT_LOCK(rt);
1039 if ((error = rt_setgate(rt, dst, gateway)) != 0) {
1040 RT_LOCK_DESTROY(rt);
1041 uma_zfree(V_rtzone, rt);
1042 senderr(error);
1043 }
1044
1045 /*
1046 * point to the (possibly newly malloc'd) dest address.
1047 */
1048 ndst = (struct sockaddr *)rt_key(rt);
1049
1050 /*
1051 * make sure it contains the value we want (masked if needed).
1052 */
1053 if (netmask) {
1054 rt_maskedcopy(dst, ndst, netmask);
1055 } else
1056 bcopy(dst, ndst, dst->sa_len);
1057
1058 /*
1059 * Note that we now have a reference to the ifa.
1060 * This moved from below so that rnh->rnh_addaddr() can
1061 * examine the ifa and ifa->ifa_ifp if it so desires.
1062 */
1063 IFAREF(ifa);
1064 rt->rt_ifa = ifa;
1065 rt->rt_ifp = ifa->ifa_ifp;
1066 rt->rt_rmx.rmx_weight = 1;
1067
1068#ifdef RADIX_MPATH
1069 /* do not permit exactly the same dst/mask/gw pair */
1070 if (rn_mpath_capable(rnh) &&
1071 rt_mpath_conflict(rnh, rt, netmask)) {
1072 if (rt->rt_ifa) {
1073 IFAFREE(rt->rt_ifa);
1074 }
1075 Free(rt_key(rt));
1076 RT_LOCK_DESTROY(rt);
1077 uma_zfree(V_rtzone, rt);
1078 senderr(EEXIST);
1079 }
1080#endif
1081
1082 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
1083 rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
1084 /*
1085 * If it still failed to go into the tree,
1086 * then un-make it (this should be a function)
1087 */
1088 if (rn == NULL) {
1089 if (rt->rt_ifa)
1090 IFAFREE(rt->rt_ifa);
1091 Free(rt_key(rt));
1092 RT_LOCK_DESTROY(rt);
1093 uma_zfree(V_rtzone, rt);
1094 senderr(EEXIST);
1095 }
1096
1097 /*
1098 * If this protocol has something to add to this then
1099 * allow it to do that as well.
1100 */
1101 if (ifa->ifa_rtrequest)
1102 ifa->ifa_rtrequest(req, rt, info);
1103
1104 /*
1105 * actually return a resultant rtentry and
1106 * give the caller a single reference.
1107 */
1108 if (ret_nrt) {
1109 *ret_nrt = rt;
1110 RT_ADDREF(rt);
1111 }
1112 RT_UNLOCK(rt);
1113 break;
1114 default:
1115 error = EOPNOTSUPP;
1116 }
1117bad:
1118 if (needlock)
1119 RADIX_NODE_HEAD_UNLOCK(rnh);
1120 return (error);
1121#undef senderr
1122}
1123
1124#undef dst
1125#undef gateway
1126#undef netmask
1127#undef ifaaddr
1128#undef ifpaddr
1129#undef flags
1130
1131int
1132rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
1133{
1134 /* XXX dst may be overwritten, can we move this to below */
1135 int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
1136#ifdef INVARIANTS
975 if (rnh == NULL)
976 return (EAFNOSUPPORT);
977 needlock = ((flags & RTF_RNH_LOCKED) == 0);
978 flags &= ~RTF_RNH_LOCKED;
979 if (needlock)
980 RADIX_NODE_HEAD_LOCK(rnh);
981 else
982 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
983 /*
984 * If we are adding a host route then we don't want to put
985 * a netmask in the tree, nor do we want to clone it.
986 */
987 if (flags & RTF_HOST)
988 netmask = NULL;
989
990 switch (req) {
991 case RTM_DELETE:
992#ifdef RADIX_MPATH
993 if (rn_mpath_capable(rnh)) {
994 error = rn_mpath_update(req, info, rnh, ret_nrt);
995 /*
996 * "bad" holds true for the success case
997 * as well
998 */
999 if (error != ENOENT)
1000 goto bad;
1001 }
1002#endif
1003 /*
1004 * Remove the item from the tree and return it.
1005 * Complain if it is not there and do no more processing.
1006 */
1007 rn = rnh->rnh_deladdr(dst, netmask, rnh);
1008 if (rn == NULL)
1009 senderr(ESRCH);
1010 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
1011 panic ("rtrequest delete");
1012 rt = RNTORT(rn);
1013 RT_LOCK(rt);
1014 RT_ADDREF(rt);
1015 rt->rt_flags &= ~RTF_UP;
1016
1017 /*
1018 * give the protocol a chance to keep things in sync.
1019 */
1020 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
1021 ifa->ifa_rtrequest(RTM_DELETE, rt, info);
1022
1023 /*
1024 * One more rtentry floating around that is not
1025 * linked to the routing table. rttrash will be decremented
1026 * when RTFREE(rt) is eventually called.
1027 */
1028 V_rttrash++;
1029
1030 /*
1031 * If the caller wants it, then it can have it,
1032 * but it's up to it to free the rtentry as we won't be
1033 * doing it.
1034 */
1035 if (ret_nrt) {
1036 *ret_nrt = rt;
1037 RT_UNLOCK(rt);
1038 } else
1039 RTFREE_LOCKED(rt);
1040 break;
1041 case RTM_RESOLVE:
1042 /*
1043 * resolve was only used for route cloning
1044 * here for compat
1045 */
1046 break;
1047 case RTM_ADD:
1048 if ((flags & RTF_GATEWAY) && !gateway)
1049 senderr(EINVAL);
1050 if (dst && gateway && (dst->sa_family != gateway->sa_family) &&
1051 (gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK))
1052 senderr(EINVAL);
1053
1054 if (info->rti_ifa == NULL && (error = rt_getifa_fib(info, fibnum)))
1055 senderr(error);
1056 ifa = info->rti_ifa;
1057 rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
1058 if (rt == NULL)
1059 senderr(ENOBUFS);
1060 RT_LOCK_INIT(rt);
1061 rt->rt_flags = RTF_UP | flags;
1062 rt->rt_fibnum = fibnum;
1063 /*
1064 * Add the gateway. Possibly re-malloc-ing the storage for it
1065 *
1066 */
1067 RT_LOCK(rt);
1068 if ((error = rt_setgate(rt, dst, gateway)) != 0) {
1069 RT_LOCK_DESTROY(rt);
1070 uma_zfree(V_rtzone, rt);
1071 senderr(error);
1072 }
1073
1074 /*
1075 * point to the (possibly newly malloc'd) dest address.
1076 */
1077 ndst = (struct sockaddr *)rt_key(rt);
1078
1079 /*
1080 * make sure it contains the value we want (masked if needed).
1081 */
1082 if (netmask) {
1083 rt_maskedcopy(dst, ndst, netmask);
1084 } else
1085 bcopy(dst, ndst, dst->sa_len);
1086
1087 /*
1088 * Note that we now have a reference to the ifa.
1089 * This moved from below so that rnh->rnh_addaddr() can
1090 * examine the ifa and ifa->ifa_ifp if it so desires.
1091 */
1092 IFAREF(ifa);
1093 rt->rt_ifa = ifa;
1094 rt->rt_ifp = ifa->ifa_ifp;
1095 rt->rt_rmx.rmx_weight = 1;
1096
1097#ifdef RADIX_MPATH
1098 /* do not permit exactly the same dst/mask/gw pair */
1099 if (rn_mpath_capable(rnh) &&
1100 rt_mpath_conflict(rnh, rt, netmask)) {
1101 if (rt->rt_ifa) {
1102 IFAFREE(rt->rt_ifa);
1103 }
1104 Free(rt_key(rt));
1105 RT_LOCK_DESTROY(rt);
1106 uma_zfree(V_rtzone, rt);
1107 senderr(EEXIST);
1108 }
1109#endif
1110
1111 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
1112 rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
1113 /*
1114 * If it still failed to go into the tree,
1115 * then un-make it (this should be a function)
1116 */
1117 if (rn == NULL) {
1118 if (rt->rt_ifa)
1119 IFAFREE(rt->rt_ifa);
1120 Free(rt_key(rt));
1121 RT_LOCK_DESTROY(rt);
1122 uma_zfree(V_rtzone, rt);
1123 senderr(EEXIST);
1124 }
1125
1126 /*
1127 * If this protocol has something to add to this then
1128 * allow it to do that as well.
1129 */
1130 if (ifa->ifa_rtrequest)
1131 ifa->ifa_rtrequest(req, rt, info);
1132
1133 /*
1134 * actually return a resultant rtentry and
1135 * give the caller a single reference.
1136 */
1137 if (ret_nrt) {
1138 *ret_nrt = rt;
1139 RT_ADDREF(rt);
1140 }
1141 RT_UNLOCK(rt);
1142 break;
1143 default:
1144 error = EOPNOTSUPP;
1145 }
1146bad:
1147 if (needlock)
1148 RADIX_NODE_HEAD_UNLOCK(rnh);
1149 return (error);
1150#undef senderr
1151}
1152
1153#undef dst
1154#undef gateway
1155#undef netmask
1156#undef ifaaddr
1157#undef ifpaddr
1158#undef flags
1159
1160int
1161rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
1162{
1163 /* XXX dst may be overwritten, can we move this to below */
1164 int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
1165#ifdef INVARIANTS
1137 INIT_VNET_NET(curvnet);
1138 struct radix_node_head *rnh =
1139 V_rt_tables[rt->rt_fibnum][dst->sa_family];
1166 struct radix_node_head *rnh;
1167
1168 rnh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family);
1140#endif
1141
1142 RT_LOCK_ASSERT(rt);
1143 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1144
1145 /*
1146 * Prepare to store the gateway in rt->rt_gateway.
1147 * Both dst and gateway are stored one after the other in the same
1148 * malloc'd chunk. If we have room, we can reuse the old buffer,
1149 * rt_gateway already points to the right place.
1150 * Otherwise, malloc a new block and update the 'dst' address.
1151 */
1152 if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway)) {
1153 caddr_t new;
1154
1155 R_Malloc(new, caddr_t, dlen + glen);
1156 if (new == NULL)
1157 return ENOBUFS;
1158 /*
1159 * XXX note, we copy from *dst and not *rt_key(rt) because
1160 * rt_setgate() can be called to initialize a newly
1161 * allocated route entry, in which case rt_key(rt) == NULL
1162 * (and also rt->rt_gateway == NULL).
1163 * Free()/free() handle a NULL argument just fine.
1164 */
1165 bcopy(dst, new, dlen);
1166 Free(rt_key(rt)); /* free old block, if any */
1167 rt_key(rt) = (struct sockaddr *)new;
1168 rt->rt_gateway = (struct sockaddr *)(new + dlen);
1169 }
1170
1171 /*
1172 * Copy the new gateway value into the memory chunk.
1173 */
1174 bcopy(gate, rt->rt_gateway, glen);
1175
1176 return (0);
1177}
1178
1179static void
1180rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
1181{
1182 register u_char *cp1 = (u_char *)src;
1183 register u_char *cp2 = (u_char *)dst;
1184 register u_char *cp3 = (u_char *)netmask;
1185 u_char *cplim = cp2 + *cp3;
1186 u_char *cplim2 = cp2 + *cp1;
1187
1188 *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
1189 cp3 += 2;
1190 if (cplim > cplim2)
1191 cplim = cplim2;
1192 while (cp2 < cplim)
1193 *cp2++ = *cp1++ & *cp3++;
1194 if (cp2 < cplim2)
1195 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
1196}
1197
1198/*
1199 * Set up a routing table entry, normally
1200 * for an interface.
1201 */
1202#define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */
1203static inline int
1204rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
1205{
1169#endif
1170
1171 RT_LOCK_ASSERT(rt);
1172 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1173
1174 /*
1175 * Prepare to store the gateway in rt->rt_gateway.
1176 * Both dst and gateway are stored one after the other in the same
1177 * malloc'd chunk. If we have room, we can reuse the old buffer,
1178 * rt_gateway already points to the right place.
1179 * Otherwise, malloc a new block and update the 'dst' address.
1180 */
1181 if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway)) {
1182 caddr_t new;
1183
1184 R_Malloc(new, caddr_t, dlen + glen);
1185 if (new == NULL)
1186 return ENOBUFS;
1187 /*
1188 * XXX note, we copy from *dst and not *rt_key(rt) because
1189 * rt_setgate() can be called to initialize a newly
1190 * allocated route entry, in which case rt_key(rt) == NULL
1191 * (and also rt->rt_gateway == NULL).
1192 * Free()/free() handle a NULL argument just fine.
1193 */
1194 bcopy(dst, new, dlen);
1195 Free(rt_key(rt)); /* free old block, if any */
1196 rt_key(rt) = (struct sockaddr *)new;
1197 rt->rt_gateway = (struct sockaddr *)(new + dlen);
1198 }
1199
1200 /*
1201 * Copy the new gateway value into the memory chunk.
1202 */
1203 bcopy(gate, rt->rt_gateway, glen);
1204
1205 return (0);
1206}
1207
1208static void
1209rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
1210{
1211 register u_char *cp1 = (u_char *)src;
1212 register u_char *cp2 = (u_char *)dst;
1213 register u_char *cp3 = (u_char *)netmask;
1214 u_char *cplim = cp2 + *cp3;
1215 u_char *cplim2 = cp2 + *cp1;
1216
1217 *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
1218 cp3 += 2;
1219 if (cplim > cplim2)
1220 cplim = cplim2;
1221 while (cp2 < cplim)
1222 *cp2++ = *cp1++ & *cp3++;
1223 if (cp2 < cplim2)
1224 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
1225}
1226
1227/*
1228 * Set up a routing table entry, normally
1229 * for an interface.
1230 */
1231#define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */
1232static inline int
1233rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
1234{
1206 INIT_VNET_NET(curvnet);
1207 struct sockaddr *dst;
1208 struct sockaddr *netmask;
1209 struct rtentry *rt = NULL;
1210 struct rt_addrinfo info;
1211 int error = 0;
1212 int startfib, endfib;
1213 char tempbuf[_SOCKADDR_TMPSIZE];
1214 int didwork = 0;
1215 int a_failure = 0;
1216 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1217
1218 if (flags & RTF_HOST) {
1219 dst = ifa->ifa_dstaddr;
1220 netmask = NULL;
1221 } else {
1222 dst = ifa->ifa_addr;
1223 netmask = ifa->ifa_netmask;
1224 }
1225 if ( dst->sa_family != AF_INET)
1226 fibnum = 0;
1227 if (fibnum == -1) {
1228 if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
1229 startfib = endfib = curthread->td_proc->p_fibnum;
1230 } else {
1231 startfib = 0;
1232 endfib = rt_numfibs - 1;
1233 }
1234 } else {
1235 KASSERT((fibnum < rt_numfibs), ("rtinit1: bad fibnum"));
1236 startfib = fibnum;
1237 endfib = fibnum;
1238 }
1239 if (dst->sa_len == 0)
1240 return(EINVAL);
1241
1242 /*
1243 * If it's a delete, check that if it exists,
1244 * it's on the correct interface or we might scrub
1245 * a route to another ifa which would
1246 * be confusing at best and possibly worse.
1247 */
1248 if (cmd == RTM_DELETE) {
1249 /*
1250 * It's a delete, so it should already exist..
1251 * If it's a net, mask off the host bits
1252 * (Assuming we have a mask)
1253 * XXX this is kinda inet specific..
1254 */
1255 if (netmask != NULL) {
1256 rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask);
1257 dst = (struct sockaddr *)tempbuf;
1258 }
1259 }
1260 /*
1261 * Now go through all the requested tables (fibs) and do the
1262 * requested action. Realistically, this will either be fib 0
1263 * for protocols that don't do multiple tables or all the
1264 * tables for those that do. XXX For this version only AF_INET.
1265 * When that changes code should be refactored to protocol
1266 * independent parts and protocol dependent parts.
1267 */
1268 for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
1269 if (cmd == RTM_DELETE) {
1270 struct radix_node_head *rnh;
1271 struct radix_node *rn;
1272 /*
1273 * Look up an rtentry that is in the routing tree and
1274 * contains the correct info.
1275 */
1235 struct sockaddr *dst;
1236 struct sockaddr *netmask;
1237 struct rtentry *rt = NULL;
1238 struct rt_addrinfo info;
1239 int error = 0;
1240 int startfib, endfib;
1241 char tempbuf[_SOCKADDR_TMPSIZE];
1242 int didwork = 0;
1243 int a_failure = 0;
1244 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1245
1246 if (flags & RTF_HOST) {
1247 dst = ifa->ifa_dstaddr;
1248 netmask = NULL;
1249 } else {
1250 dst = ifa->ifa_addr;
1251 netmask = ifa->ifa_netmask;
1252 }
1253 if ( dst->sa_family != AF_INET)
1254 fibnum = 0;
1255 if (fibnum == -1) {
1256 if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
1257 startfib = endfib = curthread->td_proc->p_fibnum;
1258 } else {
1259 startfib = 0;
1260 endfib = rt_numfibs - 1;
1261 }
1262 } else {
1263 KASSERT((fibnum < rt_numfibs), ("rtinit1: bad fibnum"));
1264 startfib = fibnum;
1265 endfib = fibnum;
1266 }
1267 if (dst->sa_len == 0)
1268 return(EINVAL);
1269
1270 /*
1271 * If it's a delete, check that if it exists,
1272 * it's on the correct interface or we might scrub
1273 * a route to another ifa which would
1274 * be confusing at best and possibly worse.
1275 */
1276 if (cmd == RTM_DELETE) {
1277 /*
1278 * It's a delete, so it should already exist..
1279 * If it's a net, mask off the host bits
1280 * (Assuming we have a mask)
1281 * XXX this is kinda inet specific..
1282 */
1283 if (netmask != NULL) {
1284 rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask);
1285 dst = (struct sockaddr *)tempbuf;
1286 }
1287 }
1288 /*
1289 * Now go through all the requested tables (fibs) and do the
1290 * requested action. Realistically, this will either be fib 0
1291 * for protocols that don't do multiple tables or all the
1292 * tables for those that do. XXX For this version only AF_INET.
1293 * When that changes code should be refactored to protocol
1294 * independent parts and protocol dependent parts.
1295 */
1296 for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
1297 if (cmd == RTM_DELETE) {
1298 struct radix_node_head *rnh;
1299 struct radix_node *rn;
1300 /*
1301 * Look up an rtentry that is in the routing tree and
1302 * contains the correct info.
1303 */
1276 if ((rnh = V_rt_tables[fibnum][dst->sa_family]) == NULL)
1304 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1305 if (rnh == NULL)
1277 /* this table doesn't exist but others might */
1278 continue;
1279 RADIX_NODE_HEAD_LOCK(rnh);
1280#ifdef RADIX_MPATH
1281 if (rn_mpath_capable(rnh)) {
1282
1283 rn = rnh->rnh_matchaddr(dst, rnh);
1284 if (rn == NULL)
1285 error = ESRCH;
1286 else {
1287 rt = RNTORT(rn);
1288 /*
1289 * for interface route the
1290 * rt->rt_gateway is sockaddr_intf
1291 * for cloning ARP entries, so
1292 * rt_mpath_matchgate must use the
1293 * interface address
1294 */
1295 rt = rt_mpath_matchgate(rt,
1296 ifa->ifa_addr);
1297 if (!rt)
1298 error = ESRCH;
1299 }
1300 }
1301 else
1302#endif
1303 rn = rnh->rnh_lookup(dst, netmask, rnh);
1304 error = (rn == NULL ||
1305 (rn->rn_flags & RNF_ROOT) ||
1306 RNTORT(rn)->rt_ifa != ifa ||
1307 !sa_equal((struct sockaddr *)rn->rn_key, dst));
1308 RADIX_NODE_HEAD_UNLOCK(rnh);
1309 if (error) {
1310 /* this is only an error if bad on ALL tables */
1311 continue;
1312 }
1313 }
1314 /*
1315 * Do the actual request
1316 */
1317 bzero((caddr_t)&info, sizeof(info));
1318 info.rti_ifa = ifa;
1319 info.rti_flags = flags | ifa->ifa_flags;
1320 info.rti_info[RTAX_DST] = dst;
1321 /*
1322 * doing this for compatibility reasons
1323 */
1324 if (cmd == RTM_ADD)
1325 info.rti_info[RTAX_GATEWAY] =
1326 (struct sockaddr *)&null_sdl;
1327 else
1328 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
1329 info.rti_info[RTAX_NETMASK] = netmask;
1330 error = rtrequest1_fib(cmd, &info, &rt, fibnum);
1331 if (error == 0 && rt != NULL) {
1332 /*
1333 * notify any listening routing agents of the change
1334 */
1335 RT_LOCK(rt);
1336#ifdef RADIX_MPATH
1337 /*
1338 * in case address alias finds the first address
1339 * e.g. ifconfig bge0 192.103.54.246/24
1340 * e.g. ifconfig bge0 192.103.54.247/24
1341 * the address set in the route is 192.103.54.246
1342 * so we need to replace it with 192.103.54.247
1343 */
1344 if (memcmp(rt->rt_ifa->ifa_addr,
1345 ifa->ifa_addr, ifa->ifa_addr->sa_len)) {
1346 IFAFREE(rt->rt_ifa);
1347 IFAREF(ifa);
1348 rt->rt_ifp = ifa->ifa_ifp;
1349 rt->rt_ifa = ifa;
1350 }
1351#endif
1352 /*
1353 * doing this for compatibility reasons
1354 */
1355 if (cmd == RTM_ADD) {
1356 ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
1357 rt->rt_ifp->if_type;
1358 ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
1359 rt->rt_ifp->if_index;
1360 }
1361 rt_newaddrmsg(cmd, ifa, error, rt);
1362 if (cmd == RTM_DELETE) {
1363 /*
1364 * If we are deleting, and we found an entry,
1365 * then it's been removed from the tree..
1366 * now throw it away.
1367 */
1368 RTFREE_LOCKED(rt);
1369 } else {
1370 if (cmd == RTM_ADD) {
1371 /*
1372 * We just wanted to add it..
1373 * we don't actually need a reference.
1374 */
1375 RT_REMREF(rt);
1376 }
1377 RT_UNLOCK(rt);
1378 }
1379 didwork = 1;
1380 }
1381 if (error)
1382 a_failure = error;
1383 }
1384 if (cmd == RTM_DELETE) {
1385 if (didwork) {
1386 error = 0;
1387 } else {
1388 /* we only give an error if it wasn't in any table */
1389 error = ((flags & RTF_HOST) ?
1390 EHOSTUNREACH : ENETUNREACH);
1391 }
1392 } else {
1393 if (a_failure) {
1394 /* return an error if any of them failed */
1395 error = a_failure;
1396 }
1397 }
1398 return (error);
1399}
1400
1401/* special one for inet internal use. may not use. */
1402int
1403rtinit_fib(struct ifaddr *ifa, int cmd, int flags)
1404{
1405 return (rtinit1(ifa, cmd, flags, -1));
1406}
1407
1408/*
1409 * Set up a routing table entry, normally
1410 * for an interface.
1411 */
1412int
1413rtinit(struct ifaddr *ifa, int cmd, int flags)
1414{
1415 struct sockaddr *dst;
1416 int fib = 0;
1417
1418 if (flags & RTF_HOST) {
1419 dst = ifa->ifa_dstaddr;
1420 } else {
1421 dst = ifa->ifa_addr;
1422 }
1423
1424 if (dst->sa_family == AF_INET)
1425 fib = -1;
1426 return (rtinit1(ifa, cmd, flags, fib));
1427}
1428
1429/* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */
1430SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);
1306 /* this table doesn't exist but others might */
1307 continue;
1308 RADIX_NODE_HEAD_LOCK(rnh);
1309#ifdef RADIX_MPATH
1310 if (rn_mpath_capable(rnh)) {
1311
1312 rn = rnh->rnh_matchaddr(dst, rnh);
1313 if (rn == NULL)
1314 error = ESRCH;
1315 else {
1316 rt = RNTORT(rn);
1317 /*
1318 * for interface route the
1319 * rt->rt_gateway is sockaddr_intf
1320 * for cloning ARP entries, so
1321 * rt_mpath_matchgate must use the
1322 * interface address
1323 */
1324 rt = rt_mpath_matchgate(rt,
1325 ifa->ifa_addr);
1326 if (!rt)
1327 error = ESRCH;
1328 }
1329 }
1330 else
1331#endif
1332 rn = rnh->rnh_lookup(dst, netmask, rnh);
1333 error = (rn == NULL ||
1334 (rn->rn_flags & RNF_ROOT) ||
1335 RNTORT(rn)->rt_ifa != ifa ||
1336 !sa_equal((struct sockaddr *)rn->rn_key, dst));
1337 RADIX_NODE_HEAD_UNLOCK(rnh);
1338 if (error) {
1339 /* this is only an error if bad on ALL tables */
1340 continue;
1341 }
1342 }
1343 /*
1344 * Do the actual request
1345 */
1346 bzero((caddr_t)&info, sizeof(info));
1347 info.rti_ifa = ifa;
1348 info.rti_flags = flags | ifa->ifa_flags;
1349 info.rti_info[RTAX_DST] = dst;
1350 /*
1351 * doing this for compatibility reasons
1352 */
1353 if (cmd == RTM_ADD)
1354 info.rti_info[RTAX_GATEWAY] =
1355 (struct sockaddr *)&null_sdl;
1356 else
1357 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
1358 info.rti_info[RTAX_NETMASK] = netmask;
1359 error = rtrequest1_fib(cmd, &info, &rt, fibnum);
1360 if (error == 0 && rt != NULL) {
1361 /*
1362 * notify any listening routing agents of the change
1363 */
1364 RT_LOCK(rt);
1365#ifdef RADIX_MPATH
1366 /*
1367 * in case address alias finds the first address
1368 * e.g. ifconfig bge0 192.103.54.246/24
1369 * e.g. ifconfig bge0 192.103.54.247/24
1370 * the address set in the route is 192.103.54.246
1371 * so we need to replace it with 192.103.54.247
1372 */
1373 if (memcmp(rt->rt_ifa->ifa_addr,
1374 ifa->ifa_addr, ifa->ifa_addr->sa_len)) {
1375 IFAFREE(rt->rt_ifa);
1376 IFAREF(ifa);
1377 rt->rt_ifp = ifa->ifa_ifp;
1378 rt->rt_ifa = ifa;
1379 }
1380#endif
1381 /*
1382 * doing this for compatibility reasons
1383 */
1384 if (cmd == RTM_ADD) {
1385 ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
1386 rt->rt_ifp->if_type;
1387 ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
1388 rt->rt_ifp->if_index;
1389 }
1390 rt_newaddrmsg(cmd, ifa, error, rt);
1391 if (cmd == RTM_DELETE) {
1392 /*
1393 * If we are deleting, and we found an entry,
1394 * then it's been removed from the tree..
1395 * now throw it away.
1396 */
1397 RTFREE_LOCKED(rt);
1398 } else {
1399 if (cmd == RTM_ADD) {
1400 /*
1401 * We just wanted to add it..
1402 * we don't actually need a reference.
1403 */
1404 RT_REMREF(rt);
1405 }
1406 RT_UNLOCK(rt);
1407 }
1408 didwork = 1;
1409 }
1410 if (error)
1411 a_failure = error;
1412 }
1413 if (cmd == RTM_DELETE) {
1414 if (didwork) {
1415 error = 0;
1416 } else {
1417 /* we only give an error if it wasn't in any table */
1418 error = ((flags & RTF_HOST) ?
1419 EHOSTUNREACH : ENETUNREACH);
1420 }
1421 } else {
1422 if (a_failure) {
1423 /* return an error if any of them failed */
1424 error = a_failure;
1425 }
1426 }
1427 return (error);
1428}
1429
1430/* special one for inet internal use. may not use. */
1431int
1432rtinit_fib(struct ifaddr *ifa, int cmd, int flags)
1433{
1434 return (rtinit1(ifa, cmd, flags, -1));
1435}
1436
1437/*
1438 * Set up a routing table entry, normally
1439 * for an interface.
1440 */
1441int
1442rtinit(struct ifaddr *ifa, int cmd, int flags)
1443{
1444 struct sockaddr *dst;
1445 int fib = 0;
1446
1447 if (flags & RTF_HOST) {
1448 dst = ifa->ifa_dstaddr;
1449 } else {
1450 dst = ifa->ifa_addr;
1451 }
1452
1453 if (dst->sa_family == AF_INET)
1454 fib = -1;
1455 return (rtinit1(ifa, cmd, flags, fib));
1456}
1457
1458/* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */
1459SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);