aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h6
-rw-r--r--net/ipv6/ipv6_sockglue.c2
-rw-r--r--net/ipv6/tcp_ipv6.c4
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/sctp/ipv6.c4
5 files changed, 12 insertions, 6 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 9059e0ed7fe3..9573c8d19153 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -377,6 +377,12 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
377 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 377 a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
378} 378}
379 379
380static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
381{
382 return ((a->s6_addr32[0] | a->s6_addr32[1]) == 0 &&
383 a->s6_addr32[2] == htonl(0x0000ffff));
384}
385
380/* 386/*
381 * find the first different bit between two addresses 387 * find the first different bit between two addresses
382 * length of address must be a multiple of 32bits 388 * length of address must be a multiple of 32bits
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 6b038aa72e88..74254fccbcc8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -249,7 +249,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
249 } 249 }
250 250
251 if (ipv6_only_sock(sk) || 251 if (ipv6_only_sock(sk) ||
252 !(ipv6_addr_type(&np->daddr) & IPV6_ADDR_MAPPED)) { 252 !ipv6_addr_v4mapped(&np->daddr)) {
253 retv = -EADDRNOTAVAIL; 253 retv = -EADDRNOTAVAIL;
254 break; 254 break;
255 } 255 }
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3e06799b37a6..a07b59c528f3 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -697,7 +697,7 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
697 if (!cmd.tcpm_keylen) { 697 if (!cmd.tcpm_keylen) {
698 if (!tcp_sk(sk)->md5sig_info) 698 if (!tcp_sk(sk)->md5sig_info)
699 return -ENOENT; 699 return -ENOENT;
700 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED) 700 if (ipv6_addr_v4mapped(&sin6->sin6_addr))
701 return tcp_v4_md5_do_del(sk, sin6->sin6_addr.s6_addr32[3]); 701 return tcp_v4_md5_do_del(sk, sin6->sin6_addr.s6_addr32[3]);
702 return tcp_v6_md5_do_del(sk, &sin6->sin6_addr); 702 return tcp_v6_md5_do_del(sk, &sin6->sin6_addr);
703 } 703 }
@@ -720,7 +720,7 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
720 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); 720 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
721 if (!newkey) 721 if (!newkey)
722 return -ENOMEM; 722 return -ENOMEM;
723 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED) { 723 if (ipv6_addr_v4mapped(&sin6->sin6_addr)) {
724 return tcp_v4_md5_do_add(sk, sin6->sin6_addr.s6_addr32[3], 724 return tcp_v4_md5_do_add(sk, sin6->sin6_addr.s6_addr32[3],
725 newkey, cmd.tcpm_keylen); 725 newkey, cmd.tcpm_keylen);
726 } 726 }
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index c347f3e30e2e..82ff26dd4470 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -612,7 +612,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
612 daddr = NULL; 612 daddr = NULL;
613 613
614 if (daddr) { 614 if (daddr) {
615 if (ipv6_addr_type(daddr) == IPV6_ADDR_MAPPED) { 615 if (ipv6_addr_v4mapped(daddr)) {
616 struct sockaddr_in sin; 616 struct sockaddr_in sin;
617 sin.sin_family = AF_INET; 617 sin.sin_family = AF_INET;
618 sin.sin_port = sin6 ? sin6->sin6_port : inet->dport; 618 sin.sin_port = sin6 ? sin6->sin6_port : inet->dport;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 670fd2740b89..ec29b97dbab9 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -493,7 +493,7 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
493 if (addr1->sa.sa_family != addr2->sa.sa_family) { 493 if (addr1->sa.sa_family != addr2->sa.sa_family) {
494 if (addr1->sa.sa_family == AF_INET && 494 if (addr1->sa.sa_family == AF_INET &&
495 addr2->sa.sa_family == AF_INET6 && 495 addr2->sa.sa_family == AF_INET6 &&
496 IPV6_ADDR_MAPPED == ipv6_addr_type(&addr2->v6.sin6_addr)) { 496 ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
497 if (addr2->v6.sin6_port == addr1->v4.sin_port && 497 if (addr2->v6.sin6_port == addr1->v4.sin_port &&
498 addr2->v6.sin6_addr.s6_addr32[3] == 498 addr2->v6.sin6_addr.s6_addr32[3] ==
499 addr1->v4.sin_addr.s_addr) 499 addr1->v4.sin_addr.s_addr)
@@ -501,7 +501,7 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
501 } 501 }
502 if (addr2->sa.sa_family == AF_INET && 502 if (addr2->sa.sa_family == AF_INET &&
503 addr1->sa.sa_family == AF_INET6 && 503 addr1->sa.sa_family == AF_INET6 &&
504 IPV6_ADDR_MAPPED == ipv6_addr_type(&addr1->v6.sin6_addr)) { 504 ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
505 if (addr1->v6.sin6_port == addr2->v4.sin_port && 505 if (addr1->v6.sin6_port == addr2->v4.sin_port &&
506 addr1->v6.sin6_addr.s6_addr32[3] == 506 addr1->v6.sin6_addr.s6_addr32[3] ==
507 addr2->v4.sin_addr.s_addr) 507 addr2->v4.sin_addr.s_addr)