From f04465bfe688e91f6097ec04e4af93b7d78a6908 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 11 Jan 2022 15:30:38 +0100 Subject: [PATCH] fix host.containers.internal entry for macvlan networks For ip/macvlan networks we cannot use the gateway as address for this hostname. In this case the gateway is normally not on the host so we just try to use a local ip instead. [NO NEW TESTS NEEDED] We cannot run macvlan networks in CI. Fixes #11351 Signed-off-by: Paul Holzinger --- libpod/container_internal_linux.go | 51 ++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 7745646b6b..28d961e4b3 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -2221,33 +2221,50 @@ func (c *Container) getHosts() string { depCtr = c } + // getLocalIP returns the non loopback local IP of the host + getLocalIP := func() string { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "" + } + for _, address := range addrs { + // check the address type and if it is not a loopback the display it + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return ipnet.IP.String() + } + } + } + return "" + } + if depCtr != nil { - for _, status := range depCtr.getNetworkStatus() { + host := "" + outer: + for net, status := range depCtr.getNetworkStatus() { + network, err := c.runtime.network.NetworkInspect(net) + // only add the host entry for bridge networks + // ip/macvlan gateway is normally not on the host + if err != nil || network.Driver != types.BridgeNetworkDriver { + continue + } for _, netInt := range status.Interfaces { for _, netAddress := range netInt.Subnets { if netAddress.Gateway != nil { - hosts += fmt.Sprintf("%s host.containers.internal\n", netAddress.Gateway.String()) + host = fmt.Sprintf("%s host.containers.internal\n", netAddress.Gateway.String()) + break outer } } } } - } else if c.config.NetMode.IsSlirp4netns() { - // getLocalIP returns the non loopback local IP of the host - getLocalIP := func() string { - addrs, err := net.InterfaceAddrs() - if err != nil { - return "" - } - for _, address := range addrs { - // check the address type and if it is not a loopback the display it - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { - return ipnet.IP.String() - } - } + // if no bridge gw was found try to use a local ip + if host == "" { + if ip := getLocalIP(); ip != "" { + host = fmt.Sprintf("%s\t%s\n", ip, "host.containers.internal") } - return "" } + hosts += host + } else if c.config.NetMode.IsSlirp4netns() { if ip := getLocalIP(); ip != "" { hosts += fmt.Sprintf("%s\t%s\n", ip, "host.containers.internal") }