• Nicolas Dichtel's avatar
    ipv6: fix neighbour resolution with raw socket · 2c6b55f4
    Nicolas Dichtel authored
    The scenario is the following: the user uses a raw socket to send an ipv6
    packet, destinated to a not-connected network, and specify a connected nh.
    Here is the corresponding python script to reproduce this scenario:
    
     import socket
     IPPROTO_RAW = 255
     send_s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IPPROTO_RAW)
     # scapy
     # p = IPv6(src='fd00:100::1', dst='fd00:200::fa')/ICMPv6EchoRequest()
     # str(p)
     req = b'`\x00\x00\x00\x00\x08:@\xfd\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xfd\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x80\x00\x81\xc0\x00\x00\x00\x00'
     send_s.sendto(req, ('fd00:175::2', 0, 0, 0))
    
    fd00:175::/64 is a connected route and fd00:200::fa is not a connected
    host.
    
    With this scenario, the kernel starts by sending a NS to resolve
    fd00:175::2. When it receives the NA, it flushes its queue and try to send
    the initial packet. But instead of sending it, it sends another NS to
    resolve fd00:200::fa, which obvioulsy fails, thus the packet is dropped. If
    the user sends again the packet, it now uses the right nh (fd00:175::2).
    
    The problem is that ip6_dst_lookup_neigh() uses the rt6i_gateway, which is
    :: because the associated route is a connected route, thus it uses the dst
    addr of the packet. Let's use rt6_nexthop() to choose the right nh.
    Signed-off-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    2c6b55f4
route.c 136 KB