aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/ip6_fib.h
diff options
context:
space:
mode:
authorGao feng <gaofeng@cn.fujitsu.com>2012-04-05 20:13:10 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-13 12:58:29 -0400
commit1716a96101c49186bb0b8491922fd3e69030235f (patch)
tree43794d2f033f439d25c63b1796e138d65fd746a8 /include/net/ip6_fib.h
parentd62f8dbb5b7771910f7c4657345df8ac93acb832 (diff)
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. rt6_check_expired check if rt6_info.dst.from is expired. ip6_rt_copy only set dst.from when the ort has flag RTF_ADDRCONF and RTF_DEFAULT.then hold the ort. ip6_dst_destroy release the ort. Add some functions to operate the RTF_EXPIRES flag and expires(from) together. and change the code to use these new adding functions. Changes from v5: modify ip6_route_add and ndisc_router_discovery to use new adding functions. Only set dst.from when the ort has flag RTF_ADDRCONF and RTF_DEFAULT.then hold the ort. Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/ip6_fib.h')
-rw-r--r--include/net/ip6_fib.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index b26bb8101981..c64778fd5e13 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -123,6 +123,48 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
123 return ((struct rt6_info *)dst)->rt6i_idev; 123 return ((struct rt6_info *)dst)->rt6i_idev;
124} 124}
125 125
126static inline void rt6_clean_expires(struct rt6_info *rt)
127{
128 if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
129 dst_release(rt->dst.from);
130
131 rt->rt6i_flags &= ~RTF_EXPIRES;
132 rt->dst.expires = 0;
133}
134
135static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
136{
137 if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
138 dst_release(rt->dst.from);
139
140 rt->rt6i_flags |= RTF_EXPIRES;
141 rt->dst.expires = expires;
142}
143
144static inline void rt6_update_expires(struct rt6_info *rt, int timeout)
145{
146 if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
147 dst_release(rt->dst.from);
148
149 dst_set_expires(&rt->dst, timeout);
150 rt->rt6i_flags |= RTF_EXPIRES;
151}
152
153static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
154{
155 struct dst_entry *new = (struct dst_entry *) from;
156
157 if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) {
158 if (new == rt->dst.from)
159 return;
160 dst_release(rt->dst.from);
161 }
162
163 rt->rt6i_flags &= ~RTF_EXPIRES;
164 rt->dst.from = new;
165 dst_hold(new);
166}
167
126struct fib6_walker_t { 168struct fib6_walker_t {
127 struct list_head lh; 169 struct list_head lh;
128 struct fib6_node *root, *node; 170 struct fib6_node *root, *node;