Skip to content

Commit

Permalink
pasta: add new --map-guest-addr option
Browse files Browse the repository at this point in the history
The --map-guest-addr option allows us to sepcify a ip that is remapped
to the actual host ip that was used by pasta. This is done to fix the
problem where connecting to the host ip was not possible as the same ip
was used in the netns.

We now set --map-guest-addr 169.254.1.2 which follows the same idea we
already used for the --dns-forward option. With that podman can use this
ip to set it for host.containers.internal which should the case where
there was no second host ip available, see
containers/podman#19213

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 committed Sep 2, 2024
1 parent c555424 commit 058ba34
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 35 deletions.
48 changes: 37 additions & 11 deletions libnetwork/pasta/pasta_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ import (
)

const (
dnsForwardOpt = "--dns-forward"
dnsForwardOpt = "--dns-forward"
mapGuestAddrOpt = "--map-guest-addr"

// dnsForwardIpv4 static ip used as nameserver address inside the netns,
// given this is a "link local" ip it should be very unlikely that it causes conflicts
dnsForwardIpv4 = "169.254.1.1"

// mapGuestAddrIpv4 static ip used as forwarder address inside the netns to reach the host,
// given this is a "link local" ip it should be very unlikely that it causes conflicts
mapGuestAddrIpv4 = "169.254.1.2"
)

type SetupOptions struct {
Expand Down Expand Up @@ -60,7 +65,7 @@ func Setup2(opts *SetupOptions) (*SetupResult, error) {
return nil, fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err)
}

cmdArgs, dnsForwardIPs, err := createPastaArgs(opts)
cmdArgs, dnsForwardIPs, mapGuestAddrIPs, err := createPastaArgs(opts)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -112,19 +117,27 @@ func Setup2(opts *SetupOptions) (*SetupResult, error) {
}

result.IPv6 = ipv6
for _, ip := range dnsForwardIPs {
result.DNSForwardIPs = filterIpFamily(dnsForwardIPs, ipv4, ipv6)
result.MapGuestAddrIPs = filterIpFamily(mapGuestAddrIPs, ipv4, ipv6)

return result, nil
}

func filterIpFamily(ips []string, ipv4, ipv6 bool) []string {
var result []string
for _, ip := range ips {
ipp := net.ParseIP(ip)
// add the namesever ip only if the address family matches
// add the ip only if the address family matches
if ipv4 && util.IsIPv4(ipp) || ipv6 && util.IsIPv6(ipp) {
result.DNSForwardIPs = append(result.DNSForwardIPs, ip)
result = append(result, ip)
}
}

return result, nil
return result
}

// createPastaArgs creates the pasta arguments, it returns the args to be passed to pasta(1) and as second arg the dns forward ips used.
func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
// createPastaArgs creates the pasta arguments, it returns the args to be passed to pasta(1)
// and as second arg the dns forward ips used. As third arg the map guest addr ips used.
func createPastaArgs(opts *SetupOptions) ([]string, []string, []string, error) {
noTCPInitPorts := true
noUDPInitPorts := true
noTCPNamespacePorts := true
Expand All @@ -149,6 +162,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
})

var dnsForwardIPs []string
var mapGuestAddrIPs []string
for i, opt := range cmdArgs {
switch opt {
case "-t", "--tcp-ports":
Expand All @@ -166,6 +180,10 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
if len(cmdArgs) > i+1 {
dnsForwardIPs = append(dnsForwardIPs, cmdArgs[i+1])
}
case mapGuestAddrOpt:
if len(cmdArgs) > i+1 {
mapGuestAddrIPs = append(mapGuestAddrIPs, cmdArgs[i+1])
}
}
}

Expand All @@ -186,7 +204,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {
noUDPInitPorts = false
cmdArgs = append(cmdArgs, "-u")
default:
return nil, nil, fmt.Errorf("can't forward protocol: %s", protocol)
return nil, nil, nil, fmt.Errorf("can't forward protocol: %s", protocol)
}

arg := fmt.Sprintf("%s%d-%d:%d-%d", addr,
Expand Down Expand Up @@ -226,5 +244,13 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) {

cmdArgs = append(cmdArgs, "--netns", opts.Netns)

return cmdArgs, dnsForwardIPs, nil
// do this as last arg
if len(mapGuestAddrIPs) == 0 {
// the user did not request custom --map-guest-addr so add our own so that we can use this
// for our own host.containers.internal host entry.
cmdArgs = append(cmdArgs, mapGuestAddrOpt, mapGuestAddrIpv4)
mapGuestAddrIPs = append(mapGuestAddrIPs, mapGuestAddrIpv4)
}

return cmdArgs, dnsForwardIPs, mapGuestAddrIPs, nil
}
113 changes: 89 additions & 24 deletions libnetwork/pasta/pasta_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ func makeSetupOptions(configArgs, extraArgs []string, ports []types.PortMapping)

func Test_createPastaArgs(t *testing.T) {
tests := []struct {
name string
input *SetupOptions
wantArgs []string
wantDnsForward []string
wantErr string
name string
input *SetupOptions
wantArgs []string
wantDnsForward []string
wantMapGuestAddr []string
wantErr string
}{
{
name: "default options",
Expand All @@ -36,8 +37,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", dnsForwardIpv4, "-t", "none", "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "basic port",
Expand All @@ -49,8 +52,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:80-80", "--dns-forward", dnsForwardIpv4, "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "port range",
Expand All @@ -62,8 +67,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-82:80-82", "--dns-forward", dnsForwardIpv4, "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "different host and container port",
Expand All @@ -75,8 +82,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:60-60", "--dns-forward", dnsForwardIpv4, "-u", "none",
"-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "tcp and udp port",
Expand All @@ -91,8 +100,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:60-60", "-u", "100-100:100-100", "--dns-forward",
dnsForwardIpv4, "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "two tcp ports",
Expand All @@ -107,8 +118,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-t", "80-80:60-60", "-t", "100-100:100-100", "--dns-forward",
dnsForwardIpv4, "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "invalid port",
Expand All @@ -131,8 +144,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-i", "eth0", "-n", "24", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "config options before extra options",
Expand All @@ -144,8 +159,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-i", "eth0", "-n", "24", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "-T option",
Expand All @@ -157,8 +174,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--tcp-ns option",
Expand All @@ -170,8 +189,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--tcp-ns", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--map-gw option",
Expand All @@ -183,8 +204,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", dnsForwardIpv4, "-t", "none",
"-u", "none", "-T", "none", "-U", "none", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
// https://github.com/containers/podman/issues/22477
Expand All @@ -196,8 +219,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "two --map-gw",
Expand All @@ -209,8 +234,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-T", "80", "--dns-forward", dnsForwardIpv4,
"-t", "none", "-u", "none", "-U", "none", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--dns-forward option",
Expand All @@ -222,8 +249,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", "192.168.255.255", "-t", "none",
"-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{"192.168.255.255"},
wantDnsForward: []string{"192.168.255.255"},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "two --dns-forward options",
Expand All @@ -235,8 +264,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--dns-forward", "192.168.255.255", "--dns-forward", "::1", "-t", "none",
"-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{"192.168.255.255", "::1"},
wantDnsForward: []string{"192.168.255.255", "::1"},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "port and custom opt",
Expand All @@ -248,8 +279,10 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "-i", "eth0", "-t", "80-80:80-80", "--dns-forward", dnsForwardIpv4,
"-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "Add verbose logging",
Expand All @@ -261,21 +294,53 @@ func Test_createPastaArgs(t *testing.T) {
wantArgs: []string{
"--config-net", "--log-file=/tmp/log", "--trace", "--debug",
"--dns-forward", dnsForwardIpv4, "-t", "none", "-u", "none", "-T", "none", "-U", "none",
"--no-map-gw", "--netns", "netns123",
"--no-map-gw", "--netns", "netns123", mapGuestAddrOpt, mapGuestAddrIpv4,
},
wantDnsForward: []string{dnsForwardIpv4},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{mapGuestAddrIpv4},
},
{
name: "--map-guest-addr option",
input: makeSetupOptions(
nil,
[]string{mapGuestAddrOpt, "192.168.255.255"},
nil,
),
wantArgs: []string{
"--config-net", mapGuestAddrOpt, "192.168.255.255", dnsForwardOpt, dnsForwardIpv4,
"-t", "none", "-u", "none", "-T", "none", "-U", "none", "--no-map-gw", "--quiet",
"--netns", "netns123",
},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{"192.168.255.255"},
},
{
name: "two --map-guest-addr options",
input: makeSetupOptions(
nil,
[]string{mapGuestAddrOpt, "192.168.255.255", mapGuestAddrOpt, "::1"},
nil,
),
wantArgs: []string{
"--config-net", mapGuestAddrOpt, "192.168.255.255", mapGuestAddrOpt, "::1",
dnsForwardOpt, dnsForwardIpv4, "-t", "none", "-u", "none", "-T", "none",
"-U", "none", "--no-map-gw", "--quiet", "--netns", "netns123",
},
wantDnsForward: []string{dnsForwardIpv4},
wantMapGuestAddr: []string{"192.168.255.255", "::1"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
args, dnsForward, err := createPastaArgs(tt.input)
args, dnsForward, mapGuestAddr, err := createPastaArgs(tt.input)
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr, "createPastaArgs error")
return
}
assert.NoError(t, err, "expect no createPastaArgs error")
assert.Equal(t, tt.wantArgs, args, "check arguments")
assert.Equal(t, tt.wantDnsForward, dnsForward, "check dns forward")
assert.Equal(t, tt.wantMapGuestAddr, mapGuestAddr, "check map guest addr")
})
}
}
3 changes: 3 additions & 0 deletions libnetwork/pasta/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ type SetupResult struct {
// DNSForwardIP is the ip used in --dns-forward, it should be added as first
// entry to resolv.conf in the container.
DNSForwardIPs []string
// MapGuestIps are the ips used for the --map-guest-addr option which
// we can use for the host.containers.internal entry.
MapGuestAddrIPs []string
// IPv6 says whenever pasta run with ipv6 support
IPv6 bool
}

0 comments on commit 058ba34

Please sign in to comment.