diff options
Diffstat (limited to 'net/ipv6/inet6_connection_sock.c')
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 8a58e8cf6646..fee46d5a2f12 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -211,6 +211,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
211 | struct flowi6 fl6; | 211 | struct flowi6 fl6; |
212 | struct dst_entry *dst; | 212 | struct dst_entry *dst; |
213 | struct in6_addr *final_p, final; | 213 | struct in6_addr *final_p, final; |
214 | int res; | ||
214 | 215 | ||
215 | memset(&fl6, 0, sizeof(fl6)); | 216 | memset(&fl6, 0, sizeof(fl6)); |
216 | fl6.flowi6_proto = sk->sk_protocol; | 217 | fl6.flowi6_proto = sk->sk_protocol; |
@@ -241,12 +242,14 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
241 | __inet6_csk_dst_store(sk, dst, NULL, NULL); | 242 | __inet6_csk_dst_store(sk, dst, NULL, NULL); |
242 | } | 243 | } |
243 | 244 | ||
244 | skb_dst_set(skb, dst_clone(dst)); | 245 | rcu_read_lock(); |
246 | skb_dst_set_noref(skb, dst); | ||
245 | 247 | ||
246 | /* Restore final destination back after routing done */ | 248 | /* Restore final destination back after routing done */ |
247 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 249 | ipv6_addr_copy(&fl6.daddr, &np->daddr); |
248 | 250 | ||
249 | return ip6_xmit(sk, skb, &fl6, np->opt); | 251 | res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); |
252 | rcu_read_unlock(); | ||
253 | return res; | ||
250 | } | 254 | } |
251 | |||
252 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); | 255 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); |