Deleted Added
full compact
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