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 --- 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 | 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 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" --- 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; | 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; |
|
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 --- 41 unchanged lines hidden (view full) --- 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 --- 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 |
|
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) --- 5 unchanged lines hidden (view full) --- 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) --- 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); |
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 --- 84 unchanged lines hidden (view full) --- 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 --- 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; |
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 } --- 45 unchanged lines hidden (view full) --- 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 } --- 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__)); |
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 */ --- 84 unchanged lines hidden (view full) --- 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 */ --- 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; |
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, --- 292 unchanged lines hidden (view full) --- 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, --- 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 */ |
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 --- 151 unchanged lines hidden (view full) --- 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 --- 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 */ |
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); --- 175 unchanged lines hidden (view full) --- 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); --- 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 |
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 --- 50 unchanged lines hidden (view full) --- 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 --- 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{ |
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; --- 53 unchanged lines hidden (view full) --- 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; --- 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 */ |
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) --- 146 unchanged lines hidden --- | 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 --- |