summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-06-04 15:49:08 +0400
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-06-05 04:02:38 +0900
commit9596cc826e2e52bfc318ca37a6c52fe3d72990a3 (patch)
treeb534c55ef8f13182d3627b73ac52d432bebf8016 /net/ipv6
parent36d926b94a9908937593e5669162305a071b9cc3 (diff)
[IPV6]: Do not change protocol for UDPv6 sockets with pending sent data.
Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ipv6_sockglue.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 1afe210d628..26b83e512a0 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -164,9 +164,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
if (sk->sk_type == SOCK_RAW)
break;
- if (sk->sk_protocol != IPPROTO_UDP &&
- sk->sk_protocol != IPPROTO_UDPLITE &&
- sk->sk_protocol != IPPROTO_TCP)
+ if (sk->sk_protocol == IPPROTO_UDP ||
+ sk->sk_protocol == IPPROTO_UDPLITE) {
+ struct udp_sock *up = udp_sk(sk);
+ if (up->pending == AF_INET6) {
+ retv = -EBUSY;
+ break;
+ }
+ } else if (sk->sk_protocol != IPPROTO_TCP)
break;
if (sk->sk_state != TCP_ESTABLISHED) {