Deleted Added
sdiff udiff text old ( 176086 ) new ( 178888 )
full compact
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 $");
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);
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
228 err = rtrequest(RTM_DELETE,
229 (struct sockaddr *)rt_key(rt),
230 rt->rt_gateway, rt_mask(rt),
231 rt->rt_flags, 0);
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
256static void
257in_rtqtimo(void *rock)
258{
259 struct radix_node_head *rnh = rock;
260 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
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{
308 struct radix_node_head *rnh = rt_tables[AF_INET];
309 struct rtqk_arg arg;
310
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);
319}
320
321/*
322 * Initialize our routing tree.
323 */
324int
325in_inithead(void **head, int off)
326{
327 struct radix_node_head *rnh;
328
329 if (!rn_inithead(head, off))
330 return 0;
331
332 if (head != (void **)&rt_tables[AF_INET]) /* BOGUS! */
333 return 1; /* only do this for the 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;
339 callout_init(&rtq_timer, CALLOUT_MPSAFE);
340 in_rtqtimo(rnh); /* kick off timeout first time */
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;
387
388 if (ifa->ifa_addr->sa_family != AF_INET)
389 return 1;
390
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? */
398 return 0;
399}