in_rmx.c (176086) | in_rmx.c (178888) |
---|---|
1/*- 2 * Copyright 1994, 1995 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all --- 27 unchanged lines hidden (view full) --- 36 * requested. 37 * 2) When such routes lose all their references, it arranges for them 38 * to be deleted in some random collection of circumstances, so that 39 * a large quantity of stale routing data is not kept in kernel memory 40 * indefinitely. See in_rtqtimo() below for the exact mechanism. 41 */ 42 43#include <sys/cdefs.h> | 1/*- 2 * Copyright 1994, 1995 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all --- 27 unchanged lines hidden (view full) --- 36 * requested. 37 * 2) When such routes lose all their references, it arranges for them 38 * to be deleted in some random collection of circumstances, so that 39 * a large quantity of stale routing data is not kept in kernel memory 40 * indefinitely. See in_rtqtimo() below for the exact mechanism. 41 */ 42 43#include <sys/cdefs.h> |
44__FBSDID("$FreeBSD: head/sys/netinet/in_rmx.c 176086 2008-02-07 11:26:52Z glebius $"); | 44__FBSDID("$FreeBSD: head/sys/netinet/in_rmx.c 178888 2008-05-09 23:03:00Z julian $"); |
45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/kernel.h> 49#include <sys/sysctl.h> 50#include <sys/socket.h> 51#include <sys/mbuf.h> 52#include <sys/syslog.h> --- 52 unchanged lines hidden (view full) --- 105 ret = rn_addroute(v_arg, n_arg, head, treenodes); 106 if (ret == NULL && rt->rt_flags & RTF_HOST) { 107 struct rtentry *rt2; 108 /* 109 * We are trying to add a host route, but can't. 110 * Find out if it is because of an 111 * ARP entry and delete it if so. 112 */ | 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/kernel.h> 49#include <sys/sysctl.h> 50#include <sys/socket.h> 51#include <sys/mbuf.h> 52#include <sys/syslog.h> --- 52 unchanged lines hidden (view full) --- 105 ret = rn_addroute(v_arg, n_arg, head, treenodes); 106 if (ret == NULL && rt->rt_flags & RTF_HOST) { 107 struct rtentry *rt2; 108 /* 109 * We are trying to add a host route, but can't. 110 * Find out if it is because of an 111 * ARP entry and delete it if so. 112 */ |
113 rt2 = rtalloc1((struct sockaddr *)sin, 0, RTF_CLONING); | 113 rt2 = in_rtalloc1((struct sockaddr *)sin, 0, 114 RTF_CLONING, rt->rt_fibnum); |
114 if (rt2) { 115 if (rt2->rt_flags & RTF_LLINFO && 116 rt2->rt_flags & RTF_HOST && 117 rt2->rt_gateway && 118 rt2->rt_gateway->sa_family == AF_LINK) { 119 rtexpunge(rt2); 120 RTFREE_LOCKED(rt2); 121 ret = rn_addroute(v_arg, n_arg, head, --- 98 unchanged lines hidden (view full) --- 220 221 if (rt->rt_flags & RTPRF_OURS) { 222 ap->found++; 223 224 if (ap->draining || rt->rt_rmx.rmx_expire <= time_uptime) { 225 if (rt->rt_refcnt > 0) 226 panic("rtqkill route really not free"); 227 | 115 if (rt2) { 116 if (rt2->rt_flags & RTF_LLINFO && 117 rt2->rt_flags & RTF_HOST && 118 rt2->rt_gateway && 119 rt2->rt_gateway->sa_family == AF_LINK) { 120 rtexpunge(rt2); 121 RTFREE_LOCKED(rt2); 122 ret = rn_addroute(v_arg, n_arg, head, --- 98 unchanged lines hidden (view full) --- 221 222 if (rt->rt_flags & RTPRF_OURS) { 223 ap->found++; 224 225 if (ap->draining || rt->rt_rmx.rmx_expire <= time_uptime) { 226 if (rt->rt_refcnt > 0) 227 panic("rtqkill route really not free"); 228 |
228 err = rtrequest(RTM_DELETE, | 229 err = in_rtrequest(RTM_DELETE, |
229 (struct sockaddr *)rt_key(rt), 230 rt->rt_gateway, rt_mask(rt), | 230 (struct sockaddr *)rt_key(rt), 231 rt->rt_gateway, rt_mask(rt), |
231 rt->rt_flags, 0); | 232 rt->rt_flags, 0, rt->rt_fibnum); |
232 if (err) { 233 log(LOG_WARNING, "in_rtqkill: error %d\n", err); 234 } else { 235 ap->killed++; 236 } 237 } else { 238 if (ap->updating && 239 (rt->rt_rmx.rmx_expire - time_uptime > --- 8 unchanged lines hidden (view full) --- 248 249 return 0; 250} 251 252#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */ 253static int rtq_timeout = RTQ_TIMEOUT; 254static struct callout rtq_timer; 255 | 233 if (err) { 234 log(LOG_WARNING, "in_rtqkill: error %d\n", err); 235 } else { 236 ap->killed++; 237 } 238 } else { 239 if (ap->updating && 240 (rt->rt_rmx.rmx_expire - time_uptime > --- 8 unchanged lines hidden (view full) --- 249 250 return 0; 251} 252 253#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */ 254static int rtq_timeout = RTQ_TIMEOUT; 255static struct callout rtq_timer; 256 |
257static void in_rtqtimo_one(void *rock); 258 |
|
256static void 257in_rtqtimo(void *rock) 258{ | 259static void 260in_rtqtimo(void *rock) 261{ |
262 int fibnum; 263 void *newrock; 264 struct timeval atv; 265 266 KASSERT((rock == (void *)rt_tables[0][AF_INET]), 267 ("in_rtqtimo: unexpected arg")); 268 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { 269 if ((newrock = rt_tables[fibnum][AF_INET]) != NULL) 270 in_rtqtimo_one(newrock); 271 } 272 atv.tv_usec = 0; 273 atv.tv_sec = rtq_timeout; 274 callout_reset(&rtq_timer, tvtohz(&atv), in_rtqtimo, rock); 275} 276 277static void 278in_rtqtimo_one(void *rock) 279{ |
|
259 struct radix_node_head *rnh = rock; 260 struct rtqk_arg arg; | 280 struct radix_node_head *rnh = rock; 281 struct rtqk_arg arg; |
261 struct timeval atv; | |
262 static time_t last_adjusted_timeout = 0; 263 264 arg.found = arg.killed = 0; 265 arg.rnh = rnh; 266 arg.nextstop = time_uptime + rtq_timeout; 267 arg.draining = arg.updating = 0; 268 RADIX_NODE_HEAD_LOCK(rnh); 269 rnh->rnh_walktree(rnh, in_rtqkill, &arg); --- 22 unchanged lines hidden (view full) --- 292#endif 293 arg.found = arg.killed = 0; 294 arg.updating = 1; 295 RADIX_NODE_HEAD_LOCK(rnh); 296 rnh->rnh_walktree(rnh, in_rtqkill, &arg); 297 RADIX_NODE_HEAD_UNLOCK(rnh); 298 } 299 | 282 static time_t last_adjusted_timeout = 0; 283 284 arg.found = arg.killed = 0; 285 arg.rnh = rnh; 286 arg.nextstop = time_uptime + rtq_timeout; 287 arg.draining = arg.updating = 0; 288 RADIX_NODE_HEAD_LOCK(rnh); 289 rnh->rnh_walktree(rnh, in_rtqkill, &arg); --- 22 unchanged lines hidden (view full) --- 312#endif 313 arg.found = arg.killed = 0; 314 arg.updating = 1; 315 RADIX_NODE_HEAD_LOCK(rnh); 316 rnh->rnh_walktree(rnh, in_rtqkill, &arg); 317 RADIX_NODE_HEAD_UNLOCK(rnh); 318 } 319 |
300 atv.tv_usec = 0; 301 atv.tv_sec = arg.nextstop - time_uptime; 302 callout_reset(&rtq_timer, tvtohz(&atv), in_rtqtimo, rock); | |
303} 304 305void 306in_rtqdrain(void) 307{ | 320} 321 322void 323in_rtqdrain(void) 324{ |
308 struct radix_node_head *rnh = rt_tables[AF_INET]; | 325 struct radix_node_head *rnh; |
309 struct rtqk_arg arg; | 326 struct rtqk_arg arg; |
327 int fibnum; |
|
310 | 328 |
311 arg.found = arg.killed = 0; 312 arg.rnh = rnh; 313 arg.nextstop = 0; 314 arg.draining = 1; 315 arg.updating = 0; 316 RADIX_NODE_HEAD_LOCK(rnh); 317 rnh->rnh_walktree(rnh, in_rtqkill, &arg); 318 RADIX_NODE_HEAD_UNLOCK(rnh); | 329 for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) { 330 rnh = rt_tables[fibnum][AF_INET]; 331 arg.found = arg.killed = 0; 332 arg.rnh = rnh; 333 arg.nextstop = 0; 334 arg.draining = 1; 335 arg.updating = 0; 336 RADIX_NODE_HEAD_LOCK(rnh); 337 rnh->rnh_walktree(rnh, in_rtqkill, &arg); 338 RADIX_NODE_HEAD_UNLOCK(rnh); 339 } |
319} 320 | 340} 341 |
342static int _in_rt_was_here; |
|
321/* 322 * Initialize our routing tree. 323 */ 324int 325in_inithead(void **head, int off) 326{ 327 struct radix_node_head *rnh; 328 | 343/* 344 * Initialize our routing tree. 345 */ 346int 347in_inithead(void **head, int off) 348{ 349 struct radix_node_head *rnh; 350 |
329 if (!rn_inithead(head, off)) | 351 /* XXX MRT 352 * This can be called from vfs_export.c too in which case 'off' 353 * will be 0. We know the correct value so just use that and 354 * return directly if it was 0. 355 * This is a hack that replaces an even worse hack on a bad hack 356 * on a bad design. After RELENG_7 this should be fixed but that 357 * will change the ABI, so for now do it this way. 358 */ 359 if (!rn_inithead(head, 32)) |
330 return 0; 331 | 360 return 0; 361 |
332 if (head != (void **)&rt_tables[AF_INET]) /* BOGUS! */ 333 return 1; /* only do this for the real routing table */ | 362 if (off == 0) /* XXX MRT see above */ 363 return 1; /* only do the rest for a real routing table */ |
334 335 rnh = *head; 336 rnh->rnh_addaddr = in_addroute; 337 rnh->rnh_matchaddr = in_matroute; 338 rnh->rnh_close = in_clsroute; | 364 365 rnh = *head; 366 rnh->rnh_addaddr = in_addroute; 367 rnh->rnh_matchaddr = in_matroute; 368 rnh->rnh_close = in_clsroute; |
339 callout_init(&rtq_timer, CALLOUT_MPSAFE); 340 in_rtqtimo(rnh); /* kick off timeout first time */ | 369 if (_in_rt_was_here == 0 ) { 370 callout_init(&rtq_timer, CALLOUT_MPSAFE); 371 in_rtqtimo(rnh); /* kick off timeout first time */ 372 _in_rt_was_here = 1; 373 } |
341 return 1; 342} 343 344/* 345 * This zaps old routes when the interface goes down or interface 346 * address is deleted. In the latter case, it deletes static routes 347 * that point to this address. If we don't do this, we may end up 348 * using the old address in the future. The ones we always want to --- 30 unchanged lines hidden (view full) --- 379 return 0; 380} 381 382int 383in_ifadown(struct ifaddr *ifa, int delete) 384{ 385 struct in_ifadown_arg arg; 386 struct radix_node_head *rnh; | 374 return 1; 375} 376 377/* 378 * This zaps old routes when the interface goes down or interface 379 * address is deleted. In the latter case, it deletes static routes 380 * that point to this address. If we don't do this, we may end up 381 * using the old address in the future. The ones we always want to --- 30 unchanged lines hidden (view full) --- 412 return 0; 413} 414 415int 416in_ifadown(struct ifaddr *ifa, int delete) 417{ 418 struct in_ifadown_arg arg; 419 struct radix_node_head *rnh; |
420 int fibnum; |
|
387 388 if (ifa->ifa_addr->sa_family != AF_INET) 389 return 1; 390 | 421 422 if (ifa->ifa_addr->sa_family != AF_INET) 423 return 1; 424 |
391 rnh = rt_tables[AF_INET]; 392 arg.ifa = ifa; 393 arg.del = delete; 394 RADIX_NODE_HEAD_LOCK(rnh); 395 rnh->rnh_walktree(rnh, in_ifadownkill, &arg); 396 RADIX_NODE_HEAD_UNLOCK(rnh); 397 ifa->ifa_flags &= ~IFA_ROUTE; /* XXXlocking? */ | 425 for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) { 426 rnh = rt_tables[fibnum][AF_INET]; 427 arg.ifa = ifa; 428 arg.del = delete; 429 RADIX_NODE_HEAD_LOCK(rnh); 430 rnh->rnh_walktree(rnh, in_ifadownkill, &arg); 431 RADIX_NODE_HEAD_UNLOCK(rnh); 432 ifa->ifa_flags &= ~IFA_ROUTE; /* XXXlocking? */ 433 } |
398 return 0; 399} | 434 return 0; 435} |
436 437/* 438 * inet versions of rt functions. These have fib extensions and 439 * for now will just reference the _fib variants. 440 * eventually this order will be reversed, 441 */ 442void 443in_rtalloc_ign(struct route *ro, u_long ignflags, u_int fibnum) 444{ 445 rtalloc_ign_fib(ro, ignflags, fibnum); 446} 447 448int 449in_rtrequest( int req, 450 struct sockaddr *dst, 451 struct sockaddr *gateway, 452 struct sockaddr *netmask, 453 int flags, 454 struct rtentry **ret_nrt, 455 u_int fibnum) 456{ 457 return (rtrequest_fib(req, dst, gateway, netmask, 458 flags, ret_nrt, fibnum)); 459} 460 461struct rtentry * 462in_rtalloc1(struct sockaddr *dst, int report, u_long ignflags, u_int fibnum) 463{ 464 return (rtalloc1_fib(dst, report, ignflags, fibnum)); 465} 466 467int 468in_rt_check(struct rtentry **lrt, struct rtentry **lrt0, 469 struct sockaddr *dst, u_int fibnum) 470{ 471 return (rt_check_fib(lrt, lrt0, dst, fibnum)); 472} 473 474void 475in_rtredirect(struct sockaddr *dst, 476 struct sockaddr *gateway, 477 struct sockaddr *netmask, 478 int flags, 479 struct sockaddr *src, 480 u_int fibnum) 481{ 482 rtredirect_fib(dst, gateway, netmask, flags, src, fibnum); 483} 484 485void 486in_rtalloc(struct route *ro, u_int fibnum) 487{ 488 rtalloc_ign_fib(ro, 0UL, fibnum); 489} 490 491#if 0 492int in_rt_getifa(struct rt_addrinfo *, u_int fibnum); 493int in_rtioctl(u_long, caddr_t, u_int); 494int in_rtrequest1(int, struct rt_addrinfo *, struct rtentry **, u_int); 495#endif 496 497 |
|