diff options
Diffstat (limited to 'net/ipv6/inet6_connection_sock.c')
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 116f94a49071..25b931709749 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -139,6 +139,41 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) | |||
139 | 139 | ||
140 | EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); | 140 | EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); |
141 | 141 | ||
142 | static inline | ||
143 | void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst, | ||
144 | struct in6_addr *daddr, struct in6_addr *saddr) | ||
145 | { | ||
146 | __ip6_dst_store(sk, dst, daddr, saddr); | ||
147 | |||
148 | #ifdef CONFIG_XFRM | ||
149 | if (dst) { | ||
150 | struct rt6_info *rt = (struct rt6_info *)dst; | ||
151 | rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid); | ||
152 | } | ||
153 | #endif | ||
154 | } | ||
155 | |||
156 | static inline | ||
157 | struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) | ||
158 | { | ||
159 | struct dst_entry *dst; | ||
160 | |||
161 | dst = __sk_dst_check(sk, cookie); | ||
162 | |||
163 | #ifdef CONFIG_XFRM | ||
164 | if (dst) { | ||
165 | struct rt6_info *rt = (struct rt6_info *)dst; | ||
166 | if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) { | ||
167 | sk->sk_dst_cache = NULL; | ||
168 | dst_release(dst); | ||
169 | dst = NULL; | ||
170 | } | ||
171 | } | ||
172 | #endif | ||
173 | |||
174 | return dst; | ||
175 | } | ||
176 | |||
142 | int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | 177 | int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) |
143 | { | 178 | { |
144 | struct sock *sk = skb->sk; | 179 | struct sock *sk = skb->sk; |
@@ -166,7 +201,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
166 | final_p = &final; | 201 | final_p = &final; |
167 | } | 202 | } |
168 | 203 | ||
169 | dst = __sk_dst_check(sk, np->dst_cookie); | 204 | dst = __inet6_csk_dst_check(sk, np->dst_cookie); |
170 | 205 | ||
171 | if (dst == NULL) { | 206 | if (dst == NULL) { |
172 | int err = ip6_dst_lookup(sk, &dst, &fl); | 207 | int err = ip6_dst_lookup(sk, &dst, &fl); |
@@ -186,7 +221,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
186 | return err; | 221 | return err; |
187 | } | 222 | } |
188 | 223 | ||
189 | __ip6_dst_store(sk, dst, NULL, NULL); | 224 | __inet6_csk_dst_store(sk, dst, NULL, NULL); |
190 | } | 225 | } |
191 | 226 | ||
192 | skb->dst = dst_clone(dst); | 227 | skb->dst = dst_clone(dst); |