Deleted Added
sdiff udiff text old ( 191734 ) new ( 193232 )
full compact
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

--- 13 unchanged lines hidden (view full) ---

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 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"

--- 47 unchanged lines hidden (view full) ---

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;
95
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

--- 41 unchanged lines hidden (view full) ---

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
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)

--- 5 unchanged lines hidden (view full) ---

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);
200 struct domain *dom;
201 struct radix_node_head **rnh;
202 int table;
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
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 */
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,
227 dom->dom_rtoffset);
228 } else {
229 break;
230 }
231 }
232 }
233 }
234

--- 84 unchanged lines hidden (view full) ---

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;
327 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
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 }

--- 45 unchanged lines hidden (view full) ---

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__));
389 rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
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 */

--- 84 unchanged lines hidden (view full) ---

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;
490 struct radix_node_head *rnh;
491
492 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
493 if (rnh == NULL) {
494 error = EAFNOSUPPORT;
495 goto out;
496 }
497
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,

--- 292 unchanged lines hidden (view full) ---

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 */
806 rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
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

--- 151 unchanged lines hidden (view full) ---

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 */
974 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
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);

--- 175 unchanged lines hidden (view full) ---

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
1166 struct radix_node_head *rnh;
1167
1168 rnh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family);
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

--- 50 unchanged lines hidden (view full) ---

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{
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;

--- 53 unchanged lines hidden (view full) ---

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 */
1304 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1305 if (rnh == NULL)
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)

--- 146 unchanged lines hidden ---