• Brian Haley's avatar
    IPv6: fix IPV6_RECVERR handling of locally-generated errors · d40a4de0
    Brian Haley authored
    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: default avatarBrian 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.htmlSigned-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d40a4de0
datagram.c 17.5 KB