IPv6: fix IPV6_RECVERR handling of locally-generated errors
authorBrian Haley <brian.haley@hp.com>
Mon, 3 May 2010 15:44:27 +0000 (15:44 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 6 May 2010 04:32:40 +0000 (21:32 -0700)
commitd40a4de0be08f005814a4fddac748fe5353208ec
tree82b5bf934623d92ec178ec62339e4ff29f23c25b
parent7df9c43fbe470628a755dfd028e58fdd7ab9b44e
IPv6: fix IPV6_RECVERR handling of locally-generated errors

I noticed when I added support for IPV6_DONTFRAG that if you set
IPV6_RECVERR and tried to send a UDP packet larger than 64K to an
IPv6 destination, you'd correctly get an EMSGSIZE, but reading from
MSG_ERRQUEUE returned the incorrect address in the cmsg:

struct msghdr:
 msg_name         0x7fff8f3c96d0
 msg_namelen      28
struct sockaddr_in6:
 sin6_family      10
 sin6_port        7639
 sin6_flowinfo    0
 sin6_addr        ::ffff:38.32.0.0
 sin6_scope_id    0  ((null))

It should have returned this in my case:

struct msghdr:
 msg_name         0x7fffd866b510
 msg_namelen      28
struct sockaddr_in6:
 sin6_family      10
 sin6_port        7639
 sin6_flowinfo    0
 sin6_addr        2620:0:a09:e000:21f:29ff:fe57:f88b
 sin6_scope_id    0  ((null))

The problem is that ipv6_recv_error() assumes that if the error
wasn't generated by ICMPv6, it's an IPv4 address sitting there,
and proceeds to create a v4-mapped address from it.

Change ipv6_icmp_error() and ipv6_local_error() to set skb->protocol
to htons(ETH_P_IPV6) so that ipv6_recv_error() knows the address
sitting right after the extended error is IPv6, else it will
incorrectly map the first octet into an IPv4-mapped IPv6 address
in the cmsg structure returned in a recvmsg() call to obtain
the error.

Signed-off-by: Brian Haley <brian.haley@hp.com>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/datagram.c