aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipv6_sockglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r--net/ipv6/ipv6_sockglue.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 430454ee5ead..1160400e9dbd 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -36,6 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/sysctl.h> 37#include <linux/sysctl.h>
38#include <linux/netfilter.h> 38#include <linux/netfilter.h>
39#include <linux/slab.h>
39 40
40#include <net/sock.h> 41#include <net/sock.h>
41#include <net/snmp.h> 42#include <net/snmp.h>
@@ -113,9 +114,9 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
113 } 114 }
114 opt = xchg(&inet6_sk(sk)->opt, opt); 115 opt = xchg(&inet6_sk(sk)->opt, opt);
115 } else { 116 } else {
116 write_lock(&sk->sk_dst_lock); 117 spin_lock(&sk->sk_dst_lock);
117 opt = xchg(&inet6_sk(sk)->opt, opt); 118 opt = xchg(&inet6_sk(sk)->opt, opt);
118 write_unlock(&sk->sk_dst_lock); 119 spin_unlock(&sk->sk_dst_lock);
119 } 120 }
120 sk_dst_reset(sk); 121 sk_dst_reset(sk);
121 122
@@ -970,14 +971,13 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
970 case IPV6_MTU: 971 case IPV6_MTU:
971 { 972 {
972 struct dst_entry *dst; 973 struct dst_entry *dst;
974
973 val = 0; 975 val = 0;
974 lock_sock(sk); 976 rcu_read_lock();
975 dst = sk_dst_get(sk); 977 dst = __sk_dst_get(sk);
976 if (dst) { 978 if (dst)
977 val = dst_mtu(dst); 979 val = dst_mtu(dst);
978 dst_release(dst); 980 rcu_read_unlock();
979 }
980 release_sock(sk);
981 if (!val) 981 if (!val)
982 return -ENOTCONN; 982 return -ENOTCONN;
983 break; 983 break;
@@ -1065,12 +1065,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1065 else 1065 else
1066 val = np->mcast_hops; 1066 val = np->mcast_hops;
1067 1067
1068 dst = sk_dst_get(sk); 1068 if (val < 0) {
1069 if (dst) { 1069 rcu_read_lock();
1070 if (val < 0) 1070 dst = __sk_dst_get(sk);
1071 if (dst)
1071 val = ip6_dst_hoplimit(dst); 1072 val = ip6_dst_hoplimit(dst);
1072 dst_release(dst); 1073 rcu_read_unlock();
1073 } 1074 }
1075
1074 if (val < 0) 1076 if (val < 0)
1075 val = sock_net(sk)->ipv6.devconf_all->hop_limit; 1077 val = sock_net(sk)->ipv6.devconf_all->hop_limit;
1076 break; 1078 break;