linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Source address fib invalidation on IPv6
@ 2016-11-11 19:29 Jason A. Donenfeld
  2016-11-11 22:14 ` David Ahern
  0 siblings, 1 reply; 28+ messages in thread
From: Jason A. Donenfeld @ 2016-11-11 19:29 UTC (permalink / raw)
  To: Netdev; +Cc: WireGuard mailing list, LKML

Hi folks,

If I'm replying to a UDP packet, I generally want to use a source
address that's the same as the destination address of the packet to
which I'm replying. For example:

Peer A sends packet: src = 10.0.0.1,  dst = 10.0.0.3
Peer B replies with: src = 10.0.0.3, dst = 10.0.0.1

But let's complicate things. Let's say Peer B has multiple IPs on an
interface: 10.0.0.2, 10.0.0.3. The default route uses 10.0.0.2. In
this case what do you think should happen?

Case 1:
Peer A sends packet: src = 10.0.0.1,  dst = 10.0.0.3
Peer B replies with: src = 10.0.0.2, dst = 10.0.0.1

Case 2:
Peer A sends packet: src = 10.0.0.1,  dst = 10.0.0.3
Peer B replies with: src = 10.0.0.3, dst = 10.0.0.1

Intuition tells me the answer is "Case 2". If you agree, keep reading.
If you disagree, stop reading here, and instead correct my poor
intuition.

So, assuming "Case 2", when Peer B receives the first packet, he notes
that packet's destination address, so that he can use it as a source
address next. When replying, Peer B sets the stored source address and
calls the routing function:

    struct flowi4 fl = {
       .saddr = from_daddr_of_previous_packet,
       .daddr = from_saddr_of_previous_packet,
    };
    rt = ip_route_output_flow(sock_net(sock), &fl, sock);

What if, however, by the time Peer B chooses to reply, his interface
no longer has that source address? No problem, because
ip_route_output_flow will return -EINVAL in that case. So, we can do
this:

    struct flowi4 fl = {
       .saddr = from_daddr_of_previous_packet,
       .daddr = from_saddr_of_previous_packet,
    };
    rt = ip_route_output_flow(sock_net(sock), &fl, sock);
    if (unlikely(IS_ERR(rt))) {
        fl.saddr = 0;
        rt = ip_route_output_flow(sock_net(sock), &fl, sock);
    }

And then all is good in the neighborhood. This solution works. Done.

But what about IPv6? That's where we get into trouble:

    struct flowi6 fl = {
       .saddr = from_daddr_of_previous_packet,
       .daddr = from_saddr_of_previous_packet,
    };
    ret = ipv6_stub->ipv6_dst_lookup(sock_net(sock), sock, &dst, &fl);

In this case, IPv6 returns a valid dst, when no interface has the
source address anymore! So, there's no way to know whether or not the
source address for replying has gone stale. We don't have a means of
falling back to inaddr_any for the source address.

Primary question: is this behavior a bug? Or is this some consequence
of a fundamental IPv6 difference with v4? Or is something else
happening here?

Thanks,
Jason

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2016-11-15 15:26 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-11 19:29 Source address fib invalidation on IPv6 Jason A. Donenfeld
2016-11-11 22:14 ` David Ahern
2016-11-12  2:18   ` Jason A. Donenfeld
2016-11-12 15:40     ` Jason A. Donenfeld
2016-11-12 18:14       ` David Ahern
2016-11-12 19:08         ` Jason A. Donenfeld
2016-11-13  0:43           ` Jason A. Donenfeld
2016-11-13  0:51             ` Hannes Frederic Sowa
2016-11-13  1:00               ` Jason A. Donenfeld
2016-11-13 13:23                 ` [PATCH] ip6_output: ensure flow saddr actually belongs to device Jason A. Donenfeld
2016-11-13 16:30                   ` David Ahern
2016-11-13 19:02                     ` [PATCH v2] " Jason A. Donenfeld
2016-11-13 20:45                       ` David Ahern
2016-11-13 23:28                         ` [PATCH v3] " Jason A. Donenfeld
2016-11-14 16:19                           ` David Ahern
2016-11-14 16:44                           ` Hannes Frederic Sowa
2016-11-14 16:55                             ` David Ahern
2016-11-14 17:04                               ` Hannes Frederic Sowa
2016-11-14 17:17                                 ` David Ahern
2016-11-14 17:33                                   ` Hannes Frederic Sowa
2016-11-14 17:48                                     ` David Ahern
2016-11-14 18:33                                       ` Hannes Frederic Sowa
2016-11-15  0:45                                         ` Jason A. Donenfeld
2016-11-15 14:45                                           ` Hannes Frederic Sowa
2016-11-15 15:26                                             ` David Ahern
2016-11-13 20:19                     ` [PATCH] " Jason A. Donenfeld
2016-11-13 20:39                       ` David Ahern
2016-11-13  0:51             ` Source address fib invalidation on IPv6 Jason A. Donenfeld

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).