From 0b0b18e404abc35d67407725bc55786d8be0e6c8 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 27 Nov 2024 14:25:08 +0100 Subject: [PATCH] libnetwork/pasta: do not ignore ipv4 link local Starting with pasta 2024_11_27.c0fbc7e there is new "local mode"[1] in pasta that defaults to setting up link local addresses in the netns when no suitable interface was found. this is done to fix the podman issue[2] where we fail to start in these cases which was a poor UX. Now the pasta change alone works fine for these users but there is one problem. Podman adds hosts entries for the container ip/name tuple and for the host.containers.internal. These entries are filtered out thus neither ipv4 or ipv6 bool was set and no addresses where added to IPAddresses. Thus podman had no info to add entries and just left them empty, while for most cases this is fine there might be a few users who expect host.containers.internal and the container name to resolve correctly. This commit changes the logic to only skip ipv6 link local addresses but allow ipv4 link local addresses. With that podman will add the proper entry. [1] https://archives.passt.top/passt-dev/20241127042725.3133538-1-sbrivio@redhat.com/ [2] https://github.com/containers/podman/issues/24614 Signed-off-by: Paul Holzinger --- libnetwork/pasta/pasta_linux.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/libnetwork/pasta/pasta_linux.go b/libnetwork/pasta/pasta_linux.go index 2ee6369ef..33fbc35e6 100644 --- a/libnetwork/pasta/pasta_linux.go +++ b/libnetwork/pasta/pasta_linux.go @@ -110,13 +110,26 @@ func Setup(opts *SetupOptions) (*SetupResult, error) { return err } for _, addr := range addrs { - // make sure to skip localhost and other special addresses - if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { - result.IPAddresses = append(result.IPAddresses, ipnet.IP) - if !ipv4 && util.IsIPv4(ipnet.IP) { + // make sure to skip loopback and multicast addresses + if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && !ipnet.IP.IsMulticast() { + if util.IsIPv4(ipnet.IP) { + result.IPAddresses = append(result.IPAddresses, ipnet.IP) ipv4 = true - } - if !ipv6 && util.IsIPv6(ipnet.IP) { + } else if !ipnet.IP.IsLinkLocalUnicast() { + // Else must be ipv6. + // We shouldn't resolve hosts.containers.internal to IPv6 + // link-local addresses, for two reasons: + // 1. even if IPv6 is disabled in pasta (--ipv4-only), the + // kernel will configure an IPv6 link-local address in the + // container, but that doesn't mean that IPv6 connectivity + // is actually working + // 2. link-local addresses need to be suffixed by the zone + // (interface) to be of any use, but we can't do it here + // + // Thus, don't include IPv6 link-local addresses in + // IPAddresses: Podman uses them for /etc/hosts entries, and + // those need to be functional. + result.IPAddresses = append(result.IPAddresses, ipnet.IP) ipv6 = true } }