summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2014-11-11 02:52:40 +0000
committermelifaro <melifaro@FreeBSD.org>2014-11-11 02:52:40 +0000
commit12580bcaa8a78094978261a456034eb3684e9f58 (patch)
tree03ac2d127be5e5ef838975d007a62d8250819cc3 /sys
parent42e544acc78653110a142e99a4c7ce581b8e3689 (diff)
downloadFreeBSD-src-12580bcaa8a78094978261a456034eb3684e9f58.zip
FreeBSD-src-12580bcaa8a78094978261a456034eb3684e9f58.tar.gz
Kill custom in_matroute() radix mathing function removing one rte mutex lock.
Initially in_matrote() in_clsroute() in their current state was introduced by r4105 20 years ago. Instead of deleting inactive routes immediately, we kept them in route table, setting RTPRF_OURS flag and some expire time. After that, either GC came or RTPRF_OURS got removed on first-packet. It was a good solution in that days (and probably another decade after that) to keep TCP metrics. However, after moving metrics to TCP hostcache in r122922, most of in_rmx functionality became unused. It might had been used for flushing icmp-originated routes before rte mutexes/refcounting, but I'm not sure about that. So it looks like this is nearly impossible to make GC do its work nowadays: in_rtkill() ignores non-RTPRF_OURS routes. route can only become RTPRF_OURS after dropping last reference via rtfree() which calls in_clsroute(), which, it turn, ignores UP and non-RTF_DYNAMIC routes. Dynamic routes can still be installed via received redirect, but they have default lifetime (no specific rt_expire) and no one has another trie walker to call RTFREE() on them. So, the changelist: * remove custom rnh_match / rnh_close matching function. * remove all GC functions * partially revert r256695 (proto3 is no more used inside kernel, it is not possible to use rt_expire from user point of view, proto3 support is not complete) * Finish r241884 (similar to this commit) and remove remaining IPv6 parts MFC after: 1 month
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/in.h6
-rw-r--r--sys/netinet/in_rmx.c241
-rw-r--r--sys/netinet/in_var.h2
-rw-r--r--sys/netinet/ip_icmp.c36
-rw-r--r--sys/netinet/ip_input.c1
-rw-r--r--sys/netinet6/in6.h6
-rw-r--r--sys/netinet6/in6_rmx.c19
7 files changed, 9 insertions, 302 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index f2dbce2..1f79761 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -619,9 +619,9 @@ int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t,
#ifdef notyet
#define IPCTL_DEFMTU 4 /* default MTU */
#endif
-#define IPCTL_RTEXPIRE 5 /* cloned route expiration time */
-#define IPCTL_RTMINEXPIRE 6 /* min value for expiration time */
-#define IPCTL_RTMAXCACHE 7 /* trigger level for dynamic expire */
+/* IPCTL_RTEXPIRE 5 deprecated */
+/* IPCTL_RTMINEXPIRE 6 deprecated */
+/* IPCTL_RTMAXCACHE 7 deprecated */
#define IPCTL_SOURCEROUTE 8 /* may perform source routes */
#define IPCTL_DIRECTEDBROADCAST 9 /* may re-broadcast received packets */
#define IPCTL_INTRQMAXLEN 10 /* max length of netisr queue */
diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c
index a48c9d8..a53a7ac 100644
--- a/sys/netinet/in_rmx.c
+++ b/sys/netinet/in_rmx.c
@@ -36,8 +36,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
-#include <sys/syslog.h>
-#include <sys/callout.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -55,8 +53,6 @@ extern int in_inithead(void **head, int off);
extern int in_detachhead(void **head, int off);
#endif
-#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
-
/*
* Do what we need to do when inserting a route.
*/
@@ -110,238 +106,6 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
return (rn_addroute(v_arg, n_arg, head, treenodes));
}
-/*
- * This code is the inverse of in_clsroute: on first reference, if we
- * were managing the route, stop doing so and set the expiration timer
- * back off again.
- */
-static struct radix_node *
-in_matroute(void *v_arg, struct radix_node_head *head)
-{
- struct radix_node *rn = rn_match(v_arg, head);
- struct rtentry *rt = (struct rtentry *)rn;
-
- if (rt) {
- RT_LOCK(rt);
- if (rt->rt_flags & RTPRF_OURS) {
- rt->rt_flags &= ~RTPRF_OURS;
- rt->rt_expire = 0;
- }
- RT_UNLOCK(rt);
- }
- return rn;
-}
-
-static VNET_DEFINE(int, rtq_reallyold) = 60*60; /* one hour is "really old" */
-#define V_rtq_reallyold VNET(rtq_reallyold)
-SYSCTL_INT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(rtq_reallyold), 0,
- "Default expiration time on dynamically learned routes");
-
-/* never automatically crank down to less */
-static VNET_DEFINE(int, rtq_minreallyold) = 10;
-#define V_rtq_minreallyold VNET(rtq_minreallyold)
-SYSCTL_INT(_net_inet_ip, IPCTL_RTMINEXPIRE, rtminexpire, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(rtq_minreallyold), 0,
- "Minimum time to attempt to hold onto dynamically learned routes");
-
-/* 128 cached routes is "too many" */
-static VNET_DEFINE(int, rtq_toomany) = 128;
-#define V_rtq_toomany VNET(rtq_toomany)
-SYSCTL_INT(_net_inet_ip, IPCTL_RTMAXCACHE, rtmaxcache, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(rtq_toomany), 0,
- "Upper limit on dynamically learned routes");
-
-/*
- * On last reference drop, mark the route as belong to us so that it can be
- * timed out.
- */
-static void
-in_clsroute(struct radix_node *rn, struct radix_node_head *head)
-{
- struct rtentry *rt = (struct rtentry *)rn;
-
- RT_LOCK_ASSERT(rt);
-
- if (!(rt->rt_flags & RTF_UP))
- return; /* prophylactic measures */
-
- if (rt->rt_flags & RTPRF_OURS)
- return;
-
- if (!(rt->rt_flags & RTF_DYNAMIC))
- return;
-
- /*
- * If rtq_reallyold is 0, just delete the route without
- * waiting for a timeout cycle to kill it.
- */
- if (V_rtq_reallyold != 0) {
- rt->rt_flags |= RTPRF_OURS;
- rt->rt_expire = time_uptime + V_rtq_reallyold;
- } else
- rt_expunge(head, rt);
-}
-
-struct rtqk_arg {
- struct radix_node_head *rnh;
- int draining;
- int killed;
- int found;
- int updating;
- time_t nextstop;
-};
-
-/*
- * Get rid of old routes. When draining, this deletes everything, even when
- * the timeout is not expired yet. When updating, this makes sure that
- * nothing has a timeout longer than the current value of rtq_reallyold.
- */
-static int
-in_rtqkill(struct radix_node *rn, void *rock)
-{
- struct rtqk_arg *ap = rock;
- struct rtentry *rt = (struct rtentry *)rn;
- int err;
-
- RADIX_NODE_HEAD_WLOCK_ASSERT(ap->rnh);
-
- if (rt->rt_flags & RTPRF_OURS) {
- ap->found++;
-
- if (ap->draining || rt->rt_expire <= time_uptime) {
- if (rt->rt_refcnt > 0)
- panic("rtqkill route really not free");
-
- err = in_rtrequest(RTM_DELETE,
- (struct sockaddr *)rt_key(rt),
- rt->rt_gateway, rt_mask(rt),
- rt->rt_flags | RTF_RNH_LOCKED, 0,
- rt->rt_fibnum);
- if (err) {
- log(LOG_WARNING, "in_rtqkill: error %d\n", err);
- } else {
- ap->killed++;
- }
- } else {
- if (ap->updating &&
- (rt->rt_expire - time_uptime > V_rtq_reallyold))
- rt->rt_expire = time_uptime + V_rtq_reallyold;
- ap->nextstop = lmin(ap->nextstop, rt->rt_expire);
- }
- }
-
- return 0;
-}
-
-#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */
-static VNET_DEFINE(int, rtq_timeout) = RTQ_TIMEOUT;
-static VNET_DEFINE(struct callout, rtq_timer);
-
-#define V_rtq_timeout VNET(rtq_timeout)
-#define V_rtq_timer VNET(rtq_timer)
-
-static void in_rtqtimo_one(void *rock);
-
-static void
-in_rtqtimo(void *rock)
-{
- CURVNET_SET((struct vnet *) rock);
- int fibnum;
- void *newrock;
- struct timeval atv;
-
- for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
- newrock = rt_tables_get_rnh(fibnum, AF_INET);
- if (newrock != NULL)
- in_rtqtimo_one(newrock);
- }
- atv.tv_usec = 0;
- atv.tv_sec = V_rtq_timeout;
- callout_reset(&V_rtq_timer, tvtohz(&atv), in_rtqtimo, rock);
- CURVNET_RESTORE();
-}
-
-static void
-in_rtqtimo_one(void *rock)
-{
- struct radix_node_head *rnh = rock;
- struct rtqk_arg arg;
- static time_t last_adjusted_timeout = 0;
-
- arg.found = arg.killed = 0;
- arg.rnh = rnh;
- arg.nextstop = time_uptime + V_rtq_timeout;
- arg.draining = arg.updating = 0;
- RADIX_NODE_HEAD_LOCK(rnh);
- rnh->rnh_walktree(rnh, in_rtqkill, &arg);
- RADIX_NODE_HEAD_UNLOCK(rnh);
-
- /*
- * Attempt to be somewhat dynamic about this:
- * If there are ``too many'' routes sitting around taking up space,
- * then crank down the timeout, and see if we can't make some more
- * go away. However, we make sure that we will never adjust more
- * than once in rtq_timeout seconds, to keep from cranking down too
- * hard.
- */
- if ((arg.found - arg.killed > V_rtq_toomany) &&
- (time_uptime - last_adjusted_timeout >= V_rtq_timeout) &&
- V_rtq_reallyold > V_rtq_minreallyold) {
- V_rtq_reallyold = 2 * V_rtq_reallyold / 3;
- if (V_rtq_reallyold < V_rtq_minreallyold) {
- V_rtq_reallyold = V_rtq_minreallyold;
- }
-
- last_adjusted_timeout = time_uptime;
-#ifdef DIAGNOSTIC
- log(LOG_DEBUG, "in_rtqtimo: adjusted rtq_reallyold to %d\n",
- V_rtq_reallyold);
-#endif
- arg.found = arg.killed = 0;
- arg.updating = 1;
- RADIX_NODE_HEAD_LOCK(rnh);
- rnh->rnh_walktree(rnh, in_rtqkill, &arg);
- RADIX_NODE_HEAD_UNLOCK(rnh);
- }
-
-}
-
-void
-in_rtqdrain(void)
-{
- VNET_ITERATOR_DECL(vnet_iter);
- struct radix_node_head *rnh;
- struct rtqk_arg arg;
- int fibnum;
-
- VNET_LIST_RLOCK_NOSLEEP();
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET(vnet_iter);
-
- for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
- rnh = rt_tables_get_rnh(fibnum, AF_INET);
- arg.found = arg.killed = 0;
- arg.rnh = rnh;
- arg.nextstop = 0;
- arg.draining = 1;
- arg.updating = 0;
- RADIX_NODE_HEAD_LOCK(rnh);
- rnh->rnh_walktree(rnh, in_rtqkill, &arg);
- RADIX_NODE_HEAD_UNLOCK(rnh);
- }
- CURVNET_RESTORE();
- }
- VNET_LIST_RUNLOCK_NOSLEEP();
-}
-
-void
-in_setmatchfunc(struct radix_node_head *rnh, int val)
-{
-
- rnh->rnh_matchaddr = (val != 0) ? rn_match : in_matroute;
-}
-
static int _in_rt_was_here;
/*
* Initialize our routing tree.
@@ -358,11 +122,7 @@ in_inithead(void **head, int off)
RADIX_NODE_HEAD_LOCK_INIT(rnh);
rnh->rnh_addaddr = in_addroute;
- in_setmatchfunc(rnh, V_drop_redirect);
- rnh->rnh_close = in_clsroute;
if (_in_rt_was_here == 0 ) {
- callout_init(&V_rtq_timer, CALLOUT_MPSAFE);
- callout_reset(&V_rtq_timer, 1, in_rtqtimo, curvnet);
_in_rt_was_here = 1;
}
return 1;
@@ -373,7 +133,6 @@ int
in_detachhead(void **head, int off)
{
- callout_drain(&V_rtq_timer);
return (1);
}
#endif
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 6f0dcbf..16edeb1 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -407,7 +407,6 @@ int in_leavegroup_locked(struct in_multi *,
/*const*/ struct in_mfilter *);
int in_control(struct socket *, u_long, caddr_t, struct ifnet *,
struct thread *);
-void in_rtqdrain(void);
int in_addprefix(struct in_ifaddr *, int);
int in_scrubprefix(struct in_ifaddr *, u_int);
void ip_input(struct mbuf *);
@@ -426,7 +425,6 @@ void in_rtredirect(struct sockaddr *, struct sockaddr *,
struct sockaddr *, int, struct sockaddr *, u_int);
int in_rtrequest(int, struct sockaddr *,
struct sockaddr *, struct sockaddr *, int, struct rtentry **, u_int);
-void in_setmatchfunc(struct radix_node_head *, int);
#if 0
int in_rt_getifa(struct rt_addrinfo *, u_int fibnum);
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 25ccb4f..845c6ec 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -115,6 +115,9 @@ SYSCTL_UINT(_net_inet_icmp, OID_AUTO, maskfake, CTLFLAG_VNET | CTLFLAG_RW,
"Fake reply to ICMP Address Mask Request packets.");
VNET_DEFINE(int, drop_redirect) = 0;
+#define V_drop_redirect VNET(drop_redirect)
+SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(drop_redirect), 0, "Ignore ICMP redirects");
static VNET_DEFINE(int, log_redirect) = 0;
#define V_log_redirect VNET(log_redirect)
@@ -163,39 +166,6 @@ static void icmp_send(struct mbuf *, struct mbuf *);
extern struct protosw inetsw[];
-static int
-sysctl_net_icmp_drop_redir(SYSCTL_HANDLER_ARGS)
-{
- int error, new;
- int i;
- struct radix_node_head *rnh;
-
- new = V_drop_redirect;
- error = sysctl_handle_int(oidp, &new, 0, req);
- if (error == 0 && req->newptr) {
- new = (new != 0) ? 1 : 0;
-
- if (new == V_drop_redirect)
- return (0);
-
- for (i = 0; i < rt_numfibs; i++) {
- if ((rnh = rt_tables_get_rnh(i, AF_INET)) == NULL)
- continue;
- RADIX_NODE_HEAD_LOCK(rnh);
- in_setmatchfunc(rnh, new);
- RADIX_NODE_HEAD_UNLOCK(rnh);
- }
-
- V_drop_redirect = new;
- }
-
- return (error);
-}
-
-SYSCTL_PROC(_net_inet_icmp, OID_AUTO, drop_redirect,
- CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0,
- sysctl_net_icmp_drop_redir, "I", "Ignore ICMP redirects");
-
/*
* Kernel module interface for updating icmpstat. The argument is an index
* into icmpstat treated as an array of u_long. While this encodes the
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 6f48d93..d0229b2 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1330,7 +1330,6 @@ ip_drain(void)
}
IPQ_UNLOCK();
VNET_LIST_RUNLOCK_NOSLEEP();
- in_rtqdrain();
}
/*
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index 7187aec..95b4a0c 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -593,9 +593,9 @@ struct ip6_mtuinfo {
#define IPV6CTL_MAPPED_ADDR 23
#endif
#define IPV6CTL_V6ONLY 24
-#define IPV6CTL_RTEXPIRE 25 /* cloned route expiration time */
-#define IPV6CTL_RTMINEXPIRE 26 /* min value for expiration time */
-#define IPV6CTL_RTMAXCACHE 27 /* trigger level for dynamic expire */
+/* IPV6CTL_RTEXPIRE 25 deprecated */
+/* IPV6CTL_RTMINEXPIRE 26 deprecated */
+/* IPV6CTL_RTMAXCACHE 27 deprecated */
#define IPV6CTL_USETEMPADDR 32 /* use temporary addresses (RFC3041) */
#define IPV6CTL_TEMPPLTIME 33 /* preferred lifetime for tmpaddrs */
diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c
index c96db6f..1403647 100644
--- a/sys/netinet6/in6_rmx.c
+++ b/sys/netinet6/in6_rmx.c
@@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
-#include <sys/sysctl.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -179,24 +178,6 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
return (ret);
}
-SYSCTL_DECL(_net_inet6_ip6);
-
-static VNET_DEFINE(int, rtq_toomany6) = 128;
- /* 128 cached routes is ``too many'' */
-#define V_rtq_toomany6 VNET(rtq_toomany6)
-SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RTMAXCACHE, rtmaxcache, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(rtq_toomany6) , 0, "");
-
-struct rtqk_arg {
- struct radix_node_head *rnh;
- int mode;
- int updating;
- int draining;
- int killed;
- int found;
- time_t nextstop;
-};
-
/*
* Age old PMTUs.
*/
OpenPOWER on IntegriCloud