lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1330324605-26617-1-git-send-email-gaofeng@cn.fujitsu.com>
Date:	Mon, 27 Feb 2012 14:36:45 +0800
From:	Gao feng <gaofeng@...fujitsu.com>
To:	davem@...emloft.net
Cc:	netdev@...r.kernel.org, eric.dumazet@...il.com,
	Gao feng <gaofeng@...fujitsu.com>
Subject: [PATCH V2] ipv6: Fix problem with expired dst cache

If the ipv6 dst cache which copy from the dst generated by ICMPV6 RA packet.
this dst cache will not check expire because it has no RTF_EXPIRES flag.
So this dst cache will always be used until the dst gc run.

Change the struct dst_entry,add a union contains new pointer from and expires.
When rt6_info.rt6i_flags has no RTF_EXPIRES flag,the dst.expires has no use.
we can use this field to point to where the dst cache copy from.
The dst.from is only used in IPV6.

In func rt6_check_expired check if rt6_info.dst.from is expired.

In func ip6_rt_copy only set dst.from when the ort has flag RTF_ADDRCONF
and RTF_DEFAULT.

Signed-off-by: Gao feng <gaofeng@...fujitsu.com>
---
 include/net/dst.h |   11 ++++++++++-
 net/ipv6/route.c  |   22 +++++++++++++++++++---
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 344c8dd..eae92f9 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -35,7 +35,16 @@ struct dst_entry {
 	struct net_device       *dev;
 	struct  dst_ops	        *ops;
 	unsigned long		_metrics;
-	unsigned long		expires;
+
+	union {
+		unsigned long		expires;
+		/*
+		 *from is used only for dst cache witch copy form
+		 *the dst generated by ipv6 RA.
+		 */
+		void			*from;
+	};
+
 	struct dst_entry	*path;
 	struct neighbour __rcu	*_neighbour;
 #ifdef CONFIG_XFRM
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8c2e3ab..cd365fe 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -316,8 +316,18 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 
 static __inline__ int rt6_check_expired(const struct rt6_info *rt)
 {
-	return (rt->rt6i_flags & RTF_EXPIRES) &&
-		time_after(jiffies, rt->dst.expires);
+	struct rt6_info *ort = NULL;
+
+	if (rt->rt6i_flags & RTF_EXPIRES) {
+		if (time_after(jiffies, rt->dst.expires))
+			return 1;
+	} else if (rt->dst.from) {
+		ort = (struct rt6_info *) rt->dst.from;
+		return (ort->rt6i_flags & RTF_EXPIRES) &&
+			time_after(jiffies, ort->dst.expires);
+	}
+
+	return 0;
 }
 
 static inline int rt6_need_strict(const struct in6_addr *daddr)
@@ -608,6 +618,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
 
 	if (rt) {
 		if (!addrconf_finite_timeout(lifetime)) {
+			rt->dst.expires = 0;
 			rt->rt6i_flags &= ~RTF_EXPIRES;
 		} else {
 			rt->dst.expires = jiffies + HZ * lifetime;
@@ -1799,7 +1810,12 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
 		if (rt->rt6i_idev)
 			in6_dev_hold(rt->rt6i_idev);
 		rt->dst.lastuse = jiffies;
-		rt->dst.expires = 0;
+
+		if ((ort->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) ==
+		    (RTF_ADDRCONF | RTF_DEFAULT))
+			rt->dst.from = (void *)ort;
+		else
+			rt->dst.expires = 0;
 
 		rt->rt6i_gateway = ort->rt6i_gateway;
 		rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ