From 1e7a4cdb1ebd81f3fff54867ae72c4b829d0916c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Wed, 20 Feb 2013 00:29:08 +0000 Subject: [PATCH] --- yaml --- r: 352831 b: refs/heads/master c: ecd9883724b78cc72ed92c98bcb1a46c764fff21 h: refs/heads/master i: 352829: 0f6e5f472bd8c553f4778c8b90b12d23b3ac90ab 352827: 48b3ff7ee506a2ce04e2459b9f9a9a8a9a49c026 352823: bcded865dde47e02b9e3e5553caa435fcf0981d4 352815: 6fb39430dee2902c79501bb397befc1ca742e3eb 352799: e457a6e40b20e0675ec3c039d00655ae79eeb493 352767: 586b3a985979b1c91ded6a97c72d728d6a607b4b v: v3 --- [refs] | 2 +- trunk/include/net/dst.h | 8 ++------ trunk/include/net/ip6_fib.h | 39 ++++++++++++------------------------- trunk/net/core/dst.c | 1 + trunk/net/ipv6/route.c | 8 +++----- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/[refs] b/[refs] index 999f0b0948c8..2c8cce9d3d8a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 68534c682e8f5c333f835818ca5a89d3e6288870 +refs/heads/master: ecd9883724b78cc72ed92c98bcb1a46c764fff21 diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 3da47e0a4a1f..853cda11e518 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -36,13 +36,9 @@ struct dst_entry { struct net_device *dev; struct dst_ops *ops; unsigned long _metrics; - union { - unsigned long expires; - /* point to where the dst_entry copied from */ - struct dst_entry *from; - }; + unsigned long expires; struct dst_entry *path; - void *__pad0; + struct dst_entry *from; #ifdef CONFIG_XFRM struct xfrm_state *xfrm; #else diff --git a/trunk/include/net/ip6_fib.h b/trunk/include/net/ip6_fib.h index 6919a501f99e..2a601e7da1bf 100644 --- a/trunk/include/net/ip6_fib.h +++ b/trunk/include/net/ip6_fib.h @@ -164,50 +164,35 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) static inline void rt6_clean_expires(struct rt6_info *rt) { - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); - rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.from = NULL; } static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) { - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); - - rt->rt6i_flags |= RTF_EXPIRES; rt->dst.expires = expires; + rt->rt6i_flags |= RTF_EXPIRES; } -static inline void rt6_update_expires(struct rt6_info *rt, int timeout) +static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) { - if (!(rt->rt6i_flags & RTF_EXPIRES)) { - if (rt->dst.from) - dst_release(rt->dst.from); - /* dst_set_expires relies on expires == 0 - * if it has not been set previously. - */ - rt->dst.expires = 0; - } - - dst_set_expires(&rt->dst, timeout); - rt->rt6i_flags |= RTF_EXPIRES; + struct rt6_info *rt; + + for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); + rt = (struct rt6_info *)rt->dst.from); + if (rt && rt != rt0) + rt0->dst.expires = rt->dst.expires; + + dst_set_expires(&rt0->dst, timeout); + rt0->rt6i_flags |= RTF_EXPIRES; } static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) { struct dst_entry *new = (struct dst_entry *) from; - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) { - if (new == rt->dst.from) - return; - dst_release(rt->dst.from); - } - rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.from = new; dst_hold(new); + rt->dst.from = new; } static inline void ip6_rt_put(struct rt6_info *rt) diff --git a/trunk/net/core/dst.c b/trunk/net/core/dst.c index ee6153e2cf43..35fd12f1a69c 100644 --- a/trunk/net/core/dst.c +++ b/trunk/net/core/dst.c @@ -179,6 +179,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, dst_init_metrics(dst, dst_default_metrics, true); dst->expires = 0UL; dst->path = dst; + dst->from = NULL; #ifdef CONFIG_XFRM dst->xfrm = NULL; #endif diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 515bb51e05a8..928266569689 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -287,6 +287,7 @@ static void ip6_dst_destroy(struct dst_entry *dst) { struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; + struct dst_entry *from = dst->from; if (!(rt->dst.flags & DST_HOST)) dst_destroy_metrics_generic(dst); @@ -296,8 +297,8 @@ static void ip6_dst_destroy(struct dst_entry *dst) in6_dev_put(idev); } - if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) - dst_release(dst->from); + dst->from = NULL; + dst_release(from); if (rt6_has_peer(rt)) { struct inet_peer *peer = rt6_peer_ptr(rt); @@ -1010,7 +1011,6 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori rt->rt6i_gateway = ort->rt6i_gateway; rt->rt6i_flags = ort->rt6i_flags; - rt6_clean_expires(rt); rt->rt6i_metric = 0; memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); @@ -1784,8 +1784,6 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == (RTF_DEFAULT | RTF_ADDRCONF)) rt6_set_from(rt, ort); - else - rt6_clean_expires(rt); rt->rt6i_metric = 0; #ifdef CONFIG_IPV6_SUBTREES