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