diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2008-07-19 02:05:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-19 02:05:40 -0400 |
commit | 7dab83de50c7b2b7ceac695a0b56fa6c0f95b0bc (patch) | |
tree | 979c6905f2ef643acccfea9ab9ed926e764e72c8 /net/sctp/socket.c | |
parent | 6d0ccbac688207ca0616ab5094932af4db4747b3 (diff) |
sctp: Support ipv6only AF_INET6 sockets.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6aba01b0ce4e..a0e879bb202d 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -308,9 +308,16 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, | |||
308 | if (len < sizeof (struct sockaddr)) | 308 | if (len < sizeof (struct sockaddr)) |
309 | return NULL; | 309 | return NULL; |
310 | 310 | ||
311 | /* Does this PF support this AF? */ | 311 | /* V4 mapped address are really of AF_INET family */ |
312 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | 312 | if (addr->sa.sa_family == AF_INET6 && |
313 | return NULL; | 313 | ipv6_addr_v4mapped(&addr->v6.sin6_addr)) { |
314 | if (!opt->pf->af_supported(AF_INET, opt)) | ||
315 | return NULL; | ||
316 | } else { | ||
317 | /* Does this PF support this AF? */ | ||
318 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | ||
319 | return NULL; | ||
320 | } | ||
314 | 321 | ||
315 | /* If we get this far, af is valid. */ | 322 | /* If we get this far, af is valid. */ |
316 | af = sctp_get_af_specific(addr->sa.sa_family); | 323 | af = sctp_get_af_specific(addr->sa.sa_family); |
@@ -4395,6 +4402,11 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, | |||
4395 | (AF_INET6 == addr->a.sa.sa_family)) | 4402 | (AF_INET6 == addr->a.sa.sa_family)) |
4396 | continue; | 4403 | continue; |
4397 | 4404 | ||
4405 | if ((PF_INET6 == sk->sk_family) && | ||
4406 | inet_v6_ipv6only(sk) && | ||
4407 | (AF_INET == addr->a.sa.sa_family)) | ||
4408 | continue; | ||
4409 | |||
4398 | cnt++; | 4410 | cnt++; |
4399 | } | 4411 | } |
4400 | rcu_read_unlock(); | 4412 | rcu_read_unlock(); |
@@ -4435,6 +4447,10 @@ static int sctp_copy_laddrs_old(struct sock *sk, __u16 port, | |||
4435 | if ((PF_INET == sk->sk_family) && | 4447 | if ((PF_INET == sk->sk_family) && |
4436 | (AF_INET6 == addr->a.sa.sa_family)) | 4448 | (AF_INET6 == addr->a.sa.sa_family)) |
4437 | continue; | 4449 | continue; |
4450 | if ((PF_INET6 == sk->sk_family) && | ||
4451 | inet_v6_ipv6only(sk) && | ||
4452 | (AF_INET == addr->a.sa.sa_family)) | ||
4453 | continue; | ||
4438 | memcpy(&temp, &addr->a, sizeof(temp)); | 4454 | memcpy(&temp, &addr->a, sizeof(temp)); |
4439 | if (!temp.v4.sin_port) | 4455 | if (!temp.v4.sin_port) |
4440 | temp.v4.sin_port = htons(port); | 4456 | temp.v4.sin_port = htons(port); |
@@ -4470,6 +4486,10 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | |||
4470 | if ((PF_INET == sk->sk_family) && | 4486 | if ((PF_INET == sk->sk_family) && |
4471 | (AF_INET6 == addr->a.sa.sa_family)) | 4487 | (AF_INET6 == addr->a.sa.sa_family)) |
4472 | continue; | 4488 | continue; |
4489 | if ((PF_INET6 == sk->sk_family) && | ||
4490 | inet_v6_ipv6only(sk) && | ||
4491 | (AF_INET == addr->a.sa.sa_family)) | ||
4492 | continue; | ||
4473 | memcpy(&temp, &addr->a, sizeof(temp)); | 4493 | memcpy(&temp, &addr->a, sizeof(temp)); |
4474 | if (!temp.v4.sin_port) | 4494 | if (!temp.v4.sin_port) |
4475 | temp.v4.sin_port = htons(port); | 4495 | temp.v4.sin_port = htons(port); |
@@ -5568,8 +5588,8 @@ pp_found: | |||
5568 | sk2->sk_state != SCTP_SS_LISTENING) | 5588 | sk2->sk_state != SCTP_SS_LISTENING) |
5569 | continue; | 5589 | continue; |
5570 | 5590 | ||
5571 | if (sctp_bind_addr_match(&ep2->base.bind_addr, addr, | 5591 | if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr, |
5572 | sctp_sk(sk))) { | 5592 | sctp_sk(sk2), sctp_sk(sk))) { |
5573 | ret = (long)sk2; | 5593 | ret = (long)sk2; |
5574 | goto fail_unlock; | 5594 | goto fail_unlock; |
5575 | } | 5595 | } |