diff options
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 26 |
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; |