Subject: [babel] Investigating ICMP behaviour of the Linux kernel in IPv6-only mode

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Tue, 15 Jun 2021 13:38:40 +0200

Hi everyone

Juliusz poked me to take a closer look at the Linux kernel behaviour
when sending ICMP messages in an IPv6-only environment, and figured I'd
share the results here. This is relevant for draft-ietf-babel-v4viav6
when it's implemented on Linux-based hosts.

What I found was that the kernel is perfectly happy to send out ICMP
messages with an all-zero source address if no real address is
configured on any interface. This can be demonstrated simply using
network namespaces like so:

# ip netns add ns0
# ip l add type veth peer netns ns0
# ip l set dev veth0 up
# ip a add 10.0.0.1/24 dev veth0
# ip a add fc00:dead:cafe:42::1/64 dev veth0
# ip r add 10.1.0.0/24 via inet6 fc00:dead:cafe:42::2
# ip -n ns0 l set dev veth0 up
# ip -n ns0 a add fc00:dead:cafe:42::2/64 dev veth0
# ip -n ns0 r add 10.0.0.0/24 via inet6 fc00:dead:cafe:42::1
# ip netns exec ns0 sysctl -w net.ipv4.icmp_ratelimit=0
# ip netns exec ns0 sysctl -w net.ipv4.ip_forward=1
# tcpdump -tpni veth0 -c 2 icmp &
# ping -w 1 10.1.0.1 > /dev/null
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 10.0.0.1 > 10.1.0.1: ICMP echo request, id 29, seq 1, length 64
IP 0.0.0.0 > 10.0.0.1: ICMP net 10.1.0.1 unreachable, length 92
2 packets captured
2 packets received by filter
0 packets dropped by kernel

This is obviously not ideal for the behaviour we want in the v4viav6
draft. I've submitted a patch[0] to make the kernel fall back to the
dummy address specified in RFC7600. In the meantime, this can also be
achieved by adding the dummy address on the 'lo' interface of the Linux
host (and if any other v4 address is configured on any interface, that
will be used as the source instead of all-zeros).

-Toke

[0] https://lore.kernel.org/netdev/[email-masked]/

---

From: Juliusz Chroboczek <[email-masked]>
Date: Tue, 15 Jun 2021 14:20:46 +0200

> I've submitted a patch[0] to make the kernel fall back to the dummy
> address specified in RFC7600.

> [0] https://lore.kernel.org/netdev/[email-masked]/

Thanks a lot, Toke.  After spending a few hours going through the maze
that is the Linux ICMP code, I decided I needed help from somebody competent.

> configured on any interface.

The question is -- what is the behaviour of PMTUd implementations when
they receive such an ICMP packet?  Do they reduce the PMTU, or do they
drop the ICMP as obviously incorrect?

I'm going to merge the v4via6 code (I've reviewed it, and I think it needs
a few fixes), and going to enable it automatically if there's at least one
IPv4 address somewhere, including the loopback interface.  Thanks a lot
for the information above, that's very helpful.

-- Juliusz

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Tue, 15 Jun 2021 14:59:18 +0200

> that is the Linux ICMP code, I decided I needed help from somebody

You're welcome! And yeah, that code does offer all the best in
kernel-style indirection :)

> drop the ICMP as obviously incorrect?

As far as I can tell by poking around in the code, the kernel will
generally drop packets with an all-zero source; see for instance this
check:

https://elixir.bootlin.com/linux/latest/source/net/ipv4/route.c#L2139

I'll leave actually testing this as an exercise for the reader ;)

> I'm going to merge the v4via6 code (I've reviewed it, and I think it
> needs a few fixes), and going to enable it automatically if there's at
> least one IPv4 address somewhere, including the loopback interface.
> Thanks a lot for the information above, that's very helpful.

Cool! You're welcome :)

-Toke