Skip to content

Commit 876c7f4

Browse files
Brian Haleyyoshfuji
authored andcommitted
[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>
1 parent 6ac7eb0 commit 876c7f4

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

net/ipv6/raw.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -805,15 +805,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
805805
fl.fl6_flowlabel = np->flow_label;
806806
}
807807

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-
817808
if (fl.oif == 0)
818809
fl.oif = sk->sk_bound_dev_if;
819810

@@ -846,7 +837,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
846837
if (err)
847838
goto out;
848839

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) */
850844
if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
851845
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
852846

net/ipv6/udp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,10 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
752752
opt = ipv6_fixup_options(&opt_space, opt);
753753

754754
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) */
756759
if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
757760
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
758761
fl.fl_ip_sport = inet->sport;

0 commit comments

Comments
 (0)