aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Haley <Brian.Haley@hp.com>2008-04-11 00:38:24 -0400
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-04-12 00:43:27 -0400
commit876c7f41961dc5172b03cbf2dca65f05003f28a0 (patch)
tree3b5644d172edf0b9d2eecfc5f6c96d41b31c9a2a
parent6ac7eb0868ccc9a2c597d6fd0b1ea09dcdc396ed (diff)
[IPv6]: Change IPv6 unspecified destination address to ::1 for raw and un-connected sockets
This patch fixes a difference between IPv4 and IPv6 when sending packets to the unspecified address (either 0.0.0.0 or ::) when using raw or un-connected UDP sockets. There are two cases where IPv6 either fails to send anything, or sends with the destination address set to ::. For example: --> ping -c1 0.0.0.0 PING 0.0.0.0 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.032 ms --> ping6 -c1 :: PING ::(::) 56 data bytes ping: sendmsg: Invalid argument Doing a sendto("0.0.0.0") reveals: 10:55:01.495090 IP localhost.32780 > localhost.7639: UDP, length 100 Doing a sendto("::") reveals: 10:56:13.262478 IP6 fe80::217:8ff:fe7d:4718.32779 > ::.7639: UDP, length 100 If you issue a connect() first in the UDP case, it will be sent to ::1, similar to what happens with TCP. This restores the BSD-ism. Signed-off-by: Brian Haley <brian.haley@hp.com> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
-rw-r--r--net/ipv6/raw.c14
-rw-r--r--net/ipv6/udp.c5
2 files changed, 8 insertions, 11 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 088b80b4ce74..059298baa1dd 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -805,15 +805,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
805 fl.fl6_flowlabel = np->flow_label; 805 fl.fl6_flowlabel = np->flow_label;
806 } 806 }
807 807
808 if (ipv6_addr_any(daddr)) {
809 /*
810 * unspecified destination address
811 * treated as error... is this correct ?
812 */
813 fl6_sock_release(flowlabel);
814 return(-EINVAL);
815 }
816
817 if (fl.oif == 0) 808 if (fl.oif == 0)
818 fl.oif = sk->sk_bound_dev_if; 809 fl.oif = sk->sk_bound_dev_if;
819 810
@@ -846,7 +837,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
846 if (err) 837 if (err)
847 goto out; 838 goto out;
848 839
849 ipv6_addr_copy(&fl.fl6_dst, daddr); 840 if (!ipv6_addr_any(daddr))
841 ipv6_addr_copy(&fl.fl6_dst, daddr);
842 else
843 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
850 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 844 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
851 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 845 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
852 846
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 30ef7dc5d403..1fd784f3e2ec 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -752,7 +752,10 @@ do_udp_sendmsg:
752 opt = ipv6_fixup_options(&opt_space, opt); 752 opt = ipv6_fixup_options(&opt_space, opt);
753 753
754 fl.proto = sk->sk_protocol; 754 fl.proto = sk->sk_protocol;
755 ipv6_addr_copy(&fl.fl6_dst, daddr); 755 if (!ipv6_addr_any(daddr))
756 ipv6_addr_copy(&fl.fl6_dst, daddr);
757 else
758 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
756 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 759 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
757 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 760 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
758 fl.fl_ip_sport = inet->sport; 761 fl.fl_ip_sport = inet->sport;