netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 10/15] ipv4: Cache input routes in fib_info nexthops.
@ 2012-07-18 18:24 David Miller
  2012-07-18 19:27 ` Joe Perches
  0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2012-07-18 18:24 UTC (permalink / raw)
  To: netdev


Caching input routes is slightly simpler than output routes, since we
don't need to be concerned with nexthop exceptions.  (locally
destined, and routed packets, never trigger PMTU events or redirects
that will be processed by us).

However, we have to elide caching for the DIRECTSRC and non-zero itag
cases.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/ip_fib.h     |    1 +
 net/ipv4/fib_semantics.c |    2 ++
 net/ipv4/route.c         |   47 ++++++++++++++++++++++++++++++++++++----------
 3 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 23c9f9e..b64a19c 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -82,6 +82,7 @@ struct fib_nh {
 	__be32			nh_saddr;
 	int			nh_saddr_genid;
 	struct rtable		*nh_rth_output;
+	struct rtable		*nh_rth_input;
 	struct fnhe_hash_bucket	*nh_exceptions;
 };
 
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 83d0f42..e55171f 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -173,6 +173,8 @@ static void free_fib_info_rcu(struct rcu_head *head)
 			free_nh_exceptions(nexthop_nh);
 		if (nexthop_nh->nh_rth_output)
 			dst_release(&nexthop_nh->nh_rth_output->dst);
+		if (nexthop_nh->nh_rth_input)
+			dst_release(&nexthop_nh->nh_rth_input->dst);
 	} endfor_nexthops(fi);
 
 	release_net(fi->fib_net);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 2e66b9a..b2f5c33 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1202,6 +1202,9 @@ static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)
 	static DEFINE_SPINLOCK(fib_cache_lock);
 	struct rtable **p = &nh->nh_rth_output;
 
+	if (rt_is_input_route(rt))
+		p = &nh->nh_rth_input;
+
 	if (*p)
 		return;
 
@@ -1228,8 +1231,7 @@ static void rt_set_nexthop(struct rtable *rt, const struct fib_result *res,
 #ifdef CONFIG_IP_ROUTE_CLASSID
 		rt->dst.tclassid = nh->nh_tclassid;
 #endif
-		if (!(rt->dst.flags & DST_HOST) &&
-		    rt_is_output_route(rt))
+		if (!(rt->dst.flags & DST_HOST))
 			rt_cache_route(nh, rt);
 	}
 
@@ -1355,11 +1357,11 @@ static int __mkroute_input(struct sk_buff *skb,
 			   __be32 daddr, __be32 saddr, u32 tos,
 			   struct rtable **result)
 {
-	struct fib_nh_exception *fnhe;
 	struct rtable *rth;
 	int err;
 	struct in_device *out_dev;
 	unsigned int flags = 0;
+	bool do_cache;
 	u32 itag;
 
 	/* get a working reference to the output device */
@@ -1402,13 +1404,21 @@ static int __mkroute_input(struct sk_buff *skb,
 		}
 	}
 
-	fnhe = NULL;
-	if (res->fi)
-		fnhe = find_exception(&FIB_RES_NH(*res), daddr);
+	do_cache = false;
+	if (res->fi) {
+		if (!(flags & RTCF_DIRECTSRC) && !itag) {
+			rth = FIB_RES_NH(*res).nh_rth_input;
+			if (rth) {
+				dst_use(&rth->dst, jiffies);
+				goto out;
+			}
+			do_cache = true;
+		}
+	}
 
 	rth = rt_dst_alloc(out_dev->dev,
 			   IN_DEV_CONF_GET(in_dev, NOPOLICY),
-			   IN_DEV_CONF_GET(out_dev, NOXFRM), false);
+			   IN_DEV_CONF_GET(out_dev, NOXFRM), do_cache);
 	if (!rth) {
 		err = -ENOBUFS;
 		goto cleanup;
@@ -1427,8 +1437,8 @@ static int __mkroute_input(struct sk_buff *skb,
 	rth->dst.input = ip_forward;
 	rth->dst.output = ip_output;
 
-	rt_set_nexthop(rth, res, fnhe, res->fi, res->type, itag);
-
+	rt_set_nexthop(rth, res, NULL, res->fi, res->type, itag);
+out:
 	*result = rth;
 	err = 0;
  cleanup:
@@ -1480,6 +1490,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 	struct rtable	*rth;
 	int		err = -EINVAL;
 	struct net    *net = dev_net(dev);
+	bool do_cache;
 
 	/* IP on this device is disabled. */
 
@@ -1493,6 +1504,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 	if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr))
 		goto martian_source;
 
+	res.fi = NULL;
 	if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0))
 		goto brd_input;
 
@@ -1568,8 +1580,20 @@ brd_input:
 	RT_CACHE_STAT_INC(in_brd);
 
 local_input:
+	do_cache = false;
+	if (res.fi) {
+		if (!(flags & RTCF_DIRECTSRC) && !itag) {
+			rth = FIB_RES_NH(res).nh_rth_input;
+			if (rth) {
+				dst_use(&rth->dst, jiffies);
+				goto set_and_out;
+			}
+			do_cache = true;
+		}
+	}
+
 	rth = rt_dst_alloc(net->loopback_dev,
-			   IN_DEV_CONF_GET(in_dev, NOPOLICY), false, false);
+			   IN_DEV_CONF_GET(in_dev, NOPOLICY), false, do_cache);
 	if (!rth)
 		goto e_nobufs;
 
@@ -1593,6 +1617,9 @@ local_input:
 		rth->dst.error= -err;
 		rth->rt_flags 	&= ~RTCF_LOCAL;
 	}
+	if (do_cache)
+		rt_cache_route(&FIB_RES_NH(res), rth);
+set_and_out:
 	skb_dst_set(skb, &rth->dst);
 	err = 0;
 	goto out;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 10/15] ipv4: Cache input routes in fib_info nexthops.
  2012-07-18 18:24 [PATCH 10/15] ipv4: Cache input routes in fib_info nexthops David Miller
@ 2012-07-18 19:27 ` Joe Perches
  2012-07-18 19:30   ` David Miller
  0 siblings, 1 reply; 3+ messages in thread
From: Joe Perches @ 2012-07-18 19:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Wed, 2012-07-18 at 11:24 -0700, David Miller wrote:
> Caching input routes is slightly simpler than output routes, since we
> don't need to be concerned with nexthop exceptions.  (locally
> destined, and routed packets, never trigger PMTU events or redirects
> that will be processed by us).
[]
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
[]
> @@ -1355,11 +1357,11 @@ static int __mkroute_input(struct sk_buff *skb,
[]
> +	do_cache = false;
> +	if (res->fi) {
> +		if (!(flags & RTCF_DIRECTSRC) && !itag) {
> +			rth = FIB_RES_NH(*res).nh_rth_input;
> +			if (rth) {
> +				dst_use(&rth->dst, jiffies);
> +				goto out;
> +			}
> +			do_cache = true;
> +		}
> +	}
[]
> @@ -1568,8 +1580,20 @@ brd_input:
[]
> +	do_cache = false;
> +	if (res.fi) {
> +		if (!(flags & RTCF_DIRECTSRC) && !itag) {
> +			rth = FIB_RES_NH(res).nh_rth_input;
> +			if (rth) {
> +				dst_use(&rth->dst, jiffies);
> +				goto set_and_out;
> +			}
> +			do_cache = true;
> +		}
> +	}

Maybe a helper like:

	if (some_do_cache_name(rth, res, itag, flags, &do_cache))
		goto foo;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 10/15] ipv4: Cache input routes in fib_info nexthops.
  2012-07-18 19:27 ` Joe Perches
@ 2012-07-18 19:30   ` David Miller
  0 siblings, 0 replies; 3+ messages in thread
From: David Miller @ 2012-07-18 19:30 UTC (permalink / raw)
  To: joe; +Cc: netdev

From: Joe Perches <joe@perches.com>
Date: Wed, 18 Jul 2012 12:27:55 -0700

> Maybe a helper like:
> 
> 	if (some_do_cache_name(rth, res, itag, flags, &do_cache))
> 		goto foo;

Yep that would make a lot of sense.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-07-18 19:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-18 18:24 [PATCH 10/15] ipv4: Cache input routes in fib_info nexthops David Miller
2012-07-18 19:27 ` Joe Perches
2012-07-18 19:30   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).