diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 78dd31b39c..d76dea2995 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -2299,6 +2299,15 @@ func (c *Container) addHosts() error { var exclude []net.IP if c.pastaResult != nil { exclude = c.pastaResult.IPAddresses + } else if c.config.NetMode.IsBridge() { + // When running rootless we have to check the rootless netns ip addresses + // to not assign a ip that is already used in the rootless netns as it would + // not be routed to the host. + // https://github.com/containers/podman/issues/22653 + info, err := c.runtime.network.RootlessNetnsInfo() + if err == nil { + exclude = info.IPAddresses + } } return etchosts.New(&etchosts.Params{ diff --git a/test/system/505-networking-pasta.bats b/test/system/505-networking-pasta.bats index 9a96c61836..80282e1c42 100644 --- a/test/system/505-networking-pasta.bats +++ b/test/system/505-networking-pasta.bats @@ -778,7 +778,7 @@ EOF assert "$output" =~ "$mac2" "mac address from cli is set on custom interface" } -### Rootless unshare testins +### Rootless unshare testing @test "Podman unshare --rootless-netns with Pasta" { skip_if_remote "unshare is local-only" @@ -794,3 +794,30 @@ EOF run_podman unshare --rootless-netns ip addr is "$output" ".*${pasta_iface}.*" } + +# https://github.com/containers/podman/issues/22653 +@test "pasta/bridge and host.containers.internal" { + skip_if_no_ipv4 "IPv4 not routable on the host" + pasta_ip="$(default_addr 4)" + + for network in "pasta" "bridge"; do + # special exit code logic needed here, it is possible that there is no host.containers.internal + # when there is only one ip one the host and that one is used by pasta. + # As such we have to deal with both cases. + run_podman '?' run --rm --network=$network $IMAGE grep host.containers.internal /etc/hosts + if [ "$status" -eq 0 ]; then + assert "$output" !~ "$pasta_ip" "pasta host ip must not be assigned ($network)" + assert "$(hostname -I)" =~ "$(cut -f1 <<<$output)" "ip is one of the host ips ($network)" + elif [ "$status" -eq 1 ]; then + # if only pasta ip then we cannot have a host.containers.internal entry + # make sure this fact is actually the case + assert "$pasta_ip" == "$(hostname -I | tr -d '[:space:]')" "pasta ip must the only one one the host ($network)" + else + die "unexpected exit code '$status' from grep or podman ($network)" + fi + done + + host_ip=$(hostname -I | cut -f 1 -d " ") + run_podman run --rm --network=pasta:-a,169.254.0.2,-g,169.254.0.1,-n,24 $IMAGE grep host.containers.internal /etc/hosts + assert "$output" =~ "^$host_ip" "uses host first ip" +}