aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliping.zhang <liping.zhang@spreadtrum.com>2016-02-19 09:07:03 +0800
committerMister Oyster <oysterized@gmail.com>2017-04-13 12:32:09 +0200
commitff31efd5ae7deca3353989432b040b28517fb657 (patch)
treeb94ac1eae011e487b2a47a0f4904a13086896ec8
parent8558623a83dc5bb686534553877d102b4e1a3504 (diff)
net: tcp: fix rtable leak in tcp_is_local[6]
ip_rt_put/ip6_rt_put call is missed after route lookup routine. So if lookup returns ok, rtable leak will happen. Change-Id: Ica137043879b4305b70401cf7e8efda24405e3ff Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com>
-rw-r--r--net/ipv4/tcp.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0d486f654..1bb6eaad1 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3528,16 +3528,24 @@ void __init tcp_init(void)
static int tcp_is_local(struct net *net, __be32 addr) {
struct rtable *rt;
struct flowi4 fl4 = { .daddr = addr };
+ int is_local;
rt = ip_route_output_key(net, &fl4);
if (IS_ERR_OR_NULL(rt))
return 0;
- return rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK);
+
+ is_local = rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK);
+ ip_rt_put(rt);
+ return is_local;
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static int tcp_is_local6(struct net *net, struct in6_addr *addr) {
struct rt6_info *rt6 = rt6_lookup(net, addr, addr, 0, 0);
- return rt6 && rt6->dst.dev && (rt6->dst.dev->flags & IFF_LOOPBACK);
+ int is_local;
+
+ is_local = rt6 && rt6->dst.dev && (rt6->dst.dev->flags & IFF_LOOPBACK);
+ ip6_rt_put(rt6);
+ return is_local;
}
#endif