Skip to content

Commit fd62a15

Browse files
committed
Support for configurable network address for user-v2
Signed-off-by: Balaji Vijayakumar <[email protected]>
1 parent 8fbc88a commit fd62a15

File tree

20 files changed

+592
-89
lines changed

20 files changed

+592
-89
lines changed

cmd/limactl/usernet.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func newUsernetCommand() *cobra.Command {
2222
hostagentCommand.Flags().StringP("endpoint", "e", "", "exposes usernet api(s) on this endpoint")
2323
hostagentCommand.Flags().String("listen-qemu", "", "listen for qemu connections")
2424
hostagentCommand.Flags().String("listen", "", "listen on a Unix socket and receive Bess-compatible FDs as SCM_RIGHTS messages")
25+
hostagentCommand.Flags().String("subnet", "192.168.5.0/24", "sets subnet value for the usernet network")
2526
hostagentCommand.Flags().Int("mtu", 1500, "mtu")
2627
return hostagentCommand
2728
}
@@ -52,6 +53,10 @@ func usernetAction(cmd *cobra.Command, _ []string) error {
5253
if err != nil {
5354
return err
5455
}
56+
subnet, err := cmd.Flags().GetString("subnet")
57+
if err != nil {
58+
return err
59+
}
5560

5661
mtu, err := cmd.Flags().GetInt("mtu")
5762
if err != nil {
@@ -67,5 +72,6 @@ func usernetAction(cmd *cobra.Command, _ []string) error {
6772
Endpoint: endpoint,
6873
QemuSocket: qemuSocket,
6974
FdSocket: fdSocket,
75+
Subnet: subnet,
7076
})
7177
}

examples/experimental/net-user-v2.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ images:
66
- location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"
77
arch: "aarch64"
88

9+
hostResolver:
10+
hosts:
11+
host.docker.internal: host.lima.internal
912
mounts:
1013
- location: "~"
1114
- location: "/tmp/lima"

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/AlecAivazis/survey/v2 v2.3.7
77
github.com/Code-Hex/vz/v3 v3.0.6
88
github.com/alessio/shellescape v1.4.2
9+
github.com/apparentlymart/go-cidr v1.1.0
910
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e
1011
github.com/cheggaaa/pb/v3 v3.1.4
1112
github.com/containerd/containerd v1.7.3
@@ -55,7 +56,6 @@ require (
5556
github.com/VividCortex/ewma v1.2.0 // indirect
5657
github.com/a8m/envsubst v1.4.2 // indirect
5758
github.com/alecthomas/participle/v2 v2.0.0 // indirect
58-
github.com/apparentlymart/go-cidr v1.1.0 // indirect
5959
github.com/davecgh/go-spew v1.1.1 // indirect
6060
github.com/digitalocean/go-libvirt v0.0.0-20220804181439-8648fbde413e // indirect
6161
github.com/dimchansky/utfbom v1.1.1 // indirect

hack/test-templates.sh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ INFO "Testing proxy settings are imported"
129129
got=$(limactl shell "$NAME" env | grep FTP_PROXY)
130130
# Expected: FTP_PROXY is set in addition to ftp_proxy, localhost is replaced
131131
# by the gateway address, and the value is set immediately without a restart
132-
expected="FTP_PROXY=http://192.168.5.2:2121"
132+
gatewayIp=$(limactl shell "$NAME" ip route show 0.0.0.0/0 dev eth0 | cut -d\ -f3)
133+
expected="FTP_PROXY=http://${gatewayIp}:2121"
133134
INFO "FTP_PROXY: expected=${expected} got=${got}"
134135
if [ "$got" != "$expected" ]; then
135136
ERROR "proxy environment variable not set to correct value"
@@ -331,10 +332,10 @@ if [[ -n ${CHECKS["user-v2"]} ]]; then
331332
secondvm="$NAME-1"
332333
"${LIMACTL_CREATE[@]}" "$FILE" --name "$secondvm"
333334
limactl start "$secondvm"
334-
guestNewip="$(limactl shell "$secondvm" ip -4 -j addr show dev eth0 | jq -r '.[0].addr_info[0].local')"
335-
INFO "IP of $secondvm is $guestNewip"
335+
secondvmDNS="lima-$secondvm.internal"
336+
INFO "DNS of $secondvm is $secondvmDNS"
336337
set -x
337-
if ! limactl shell "$NAME" ping -c 1 "$guestNewip"; then
338+
if ! limactl shell "$NAME" ping -c 1 "$secondvmDNS"; then
338339
ERROR "Failed to do vm->vm communication via user-v2"
339340
INFO "Stopping \"$secondvm\""
340341
limactl stop "$secondvm"

pkg/cidata/cidata.TEMPLATE.d/boot/09-host-dns-setup.sh

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ if command -v iptables >/dev/null 2>&1; then
1818
# Remove old rules
1919
iptables --table nat --flush ${chain}
2020
# Add rules for the existing ip:port
21-
iptables --table nat --append "${chain}" --destination "${LIMA_CIDATA_SLIRP_DNS}" --protocol udp --dport 53 --jump DNAT \
22-
--to-destination "${LIMA_CIDATA_SLIRP_GATEWAY}:${LIMA_CIDATA_UDP_DNS_LOCAL_PORT}"
23-
iptables --table nat --append "${chain}" --destination "${LIMA_CIDATA_SLIRP_DNS}" --protocol tcp --dport 53 --jump DNAT \
24-
--to-destination "${LIMA_CIDATA_SLIRP_GATEWAY}:${LIMA_CIDATA_TCP_DNS_LOCAL_PORT}"
21+
if [ -n "${LIMA_CIDATA_UDP_DNS_LOCAL_PORT}" ] && [ "${LIMA_CIDATA_UDP_DNS_LOCAL_PORT}" -ne 0 ]; then
22+
iptables --table nat --append "${chain}" --destination "${LIMA_CIDATA_SLIRP_DNS}" --protocol udp --dport 53 --jump DNAT \
23+
--to-destination "${LIMA_CIDATA_SLIRP_GATEWAY}:${LIMA_CIDATA_UDP_DNS_LOCAL_PORT}"
24+
fi
25+
if [ -n "${LIMA_CIDATA_TCP_DNS_LOCAL_PORT}" ] && [ "${LIMA_CIDATA_TCP_DNS_LOCAL_PORT}" -ne 0 ]; then
26+
iptables --table nat --append "${chain}" --destination "${LIMA_CIDATA_SLIRP_DNS}" --protocol tcp --dport 53 --jump DNAT \
27+
--to-destination "${LIMA_CIDATA_SLIRP_GATEWAY}:${LIMA_CIDATA_TCP_DNS_LOCAL_PORT}"
28+
fi
2529
fi

pkg/cidata/cidata.go

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ import (
1212
"strings"
1313
"time"
1414

15-
"github.com/lima-vm/lima/pkg/networks"
16-
1715
"github.com/docker/go-units"
1816
"github.com/lima-vm/lima/pkg/iso9660util"
1917
"github.com/lima-vm/lima/pkg/limayaml"
2018
"github.com/lima-vm/lima/pkg/localpathutil"
19+
"github.com/lima-vm/lima/pkg/networks"
20+
"github.com/lima-vm/lima/pkg/networks/usernet"
2121
"github.com/lima-vm/lima/pkg/osutil"
2222
"github.com/lima-vm/lima/pkg/sshutil"
2323
"github.com/lima-vm/lima/pkg/store/filenames"
@@ -35,7 +35,7 @@ var netLookupIP = func(host string) []net.IP {
3535
return ips
3636
}
3737

38-
func setupEnv(y *limayaml.LimaYAML) (map[string]string, error) {
38+
func setupEnv(y *limayaml.LimaYAML, args TemplateArgs) (map[string]string, error) {
3939
// Start with the proxy variables from the system settings.
4040
env, err := osutil.ProxySettings()
4141
if err != nil {
@@ -74,7 +74,7 @@ func setupEnv(y *limayaml.LimaYAML) (map[string]string, error) {
7474

7575
for _, ip := range netLookupIP(u.Hostname()) {
7676
if ip.IsLoopback() {
77-
newHost := networks.SlirpGateway
77+
newHost := args.SlirpGateway
7878
if u.Port() != "" {
7979
newHost = net.JoinHostPort(newHost, u.Port())
8080
}
@@ -124,11 +124,34 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
124124
GuestInstallPrefix: *y.GuestInstallPrefix,
125125
Containerd: Containerd{System: *y.Containerd.System, User: *y.Containerd.User},
126126
SlirpNICName: networks.SlirpNICName,
127-
SlirpGateway: networks.SlirpGateway,
128-
SlirpDNS: networks.SlirpDNS,
129-
SlirpIPAddress: networks.SlirpIPAddress,
130-
RosettaEnabled: *y.Rosetta.Enabled,
131-
RosettaBinFmt: *y.Rosetta.BinFmt,
127+
128+
RosettaEnabled: *y.Rosetta.Enabled,
129+
RosettaBinFmt: *y.Rosetta.BinFmt,
130+
}
131+
132+
firstUsernetIndex := limayaml.FirstUsernetIndex(y)
133+
var subnet net.IP
134+
135+
if firstUsernetIndex != -1 {
136+
usernetName := y.Networks[firstUsernetIndex].Lima
137+
subnet, err = usernet.Subnet(usernetName)
138+
if err != nil {
139+
return err
140+
}
141+
args.SlirpGateway = usernet.GatewayIP(subnet)
142+
args.SlirpDNS = usernet.GatewayIP(subnet)
143+
} else {
144+
subnet, err = usernet.ParseSubnet(networks.SlirpNetwork)
145+
if err != nil {
146+
return err
147+
}
148+
args.SlirpGateway = usernet.GatewayIP(subnet)
149+
if *y.VMType == limayaml.VZ {
150+
args.SlirpDNS = usernet.GatewayIP(subnet)
151+
} else {
152+
args.SlirpDNS = usernet.DNSIP(subnet)
153+
}
154+
args.SlirpIPAddress = networks.SlirpIPAddress
132155
}
133156

134157
// change instance id on every boot so network config will be processed again
@@ -221,24 +244,24 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
221244
})
222245
}
223246

224-
slirpMACAddress := limayaml.MACAddress(instDir)
225-
args.Networks = append(args.Networks, Network{MACAddress: slirpMACAddress, Interface: networks.SlirpNICName})
226-
firstUsernetIndex := limayaml.FirstUsernetIndex(y)
247+
args.Networks = append(args.Networks, Network{MACAddress: limayaml.MACAddress(instDir), Interface: networks.SlirpNICName})
227248
for i, nw := range y.Networks {
228249
if i == firstUsernetIndex {
229250
continue
230251
}
231252
args.Networks = append(args.Networks, Network{MACAddress: nw.MACAddress, Interface: nw.Interface})
232253
}
233254

234-
args.Env, err = setupEnv(y)
255+
args.Env, err = setupEnv(y, args)
235256
if err != nil {
236257
return err
237258
}
238-
if *y.HostResolver.Enabled {
259+
if firstUsernetIndex != -1 || *y.VMType == limayaml.VZ {
260+
args.DNSAddresses = append(args.DNSAddresses, args.SlirpDNS)
261+
} else if *y.HostResolver.Enabled {
239262
args.UDPDNSLocalPort = udpDNSLocalPort
240263
args.TCPDNSLocalPort = tcpDNSLocalPort
241-
args.DNSAddresses = append(args.DNSAddresses, networks.SlirpDNS)
264+
args.DNSAddresses = append(args.DNSAddresses, args.SlirpDNS)
242265
} else if len(y.DNS) > 0 {
243266
for _, addr := range y.DNS {
244267
args.DNSAddresses = append(args.DNSAddresses, addr.String())

pkg/cidata/cidata_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ func TestSetupEnv(t *testing.T) {
4848
t.Run(httpProxy.Host, func(t *testing.T) {
4949
envKey := "http_proxy"
5050
envValue := httpProxy.String()
51-
envs, err := setupEnv(&limayaml.LimaYAML{PropagateProxyEnv: pointer.Bool(false), Env: map[string]string{envKey: envValue}})
51+
templateArgs := TemplateArgs{SlirpGateway: networks.SlirpGateway}
52+
envs, err := setupEnv(&limayaml.LimaYAML{PropagateProxyEnv: pointer.Bool(false), Env: map[string]string{envKey: envValue}}, templateArgs)
5253
assert.NilError(t, err)
5354
assert.Equal(t, envs[envKey], strings.ReplaceAll(envValue, httpProxy.Hostname(), networks.SlirpGateway))
5455
})
@@ -58,7 +59,8 @@ func TestSetupEnv(t *testing.T) {
5859
func TestSetupInvalidEnv(t *testing.T) {
5960
envKey := "http_proxy"
6061
envValue := "://localhost:8080"
61-
envs, err := setupEnv(&limayaml.LimaYAML{PropagateProxyEnv: pointer.Bool(false), Env: map[string]string{envKey: envValue}})
62+
templateArgs := TemplateArgs{SlirpGateway: networks.SlirpGateway}
63+
envs, err := setupEnv(&limayaml.LimaYAML{PropagateProxyEnv: pointer.Bool(false), Env: map[string]string{envKey: envValue}}, templateArgs)
6264
assert.NilError(t, err)
6365
assert.Equal(t, envs[envKey], envValue)
6466
}

pkg/hostagent/hostagent.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ func (a *HostAgent) Run(ctx context.Context) error {
267267
a.emitEvent(ctx, exitingEv)
268268
}()
269269

270-
if *a.y.HostResolver.Enabled {
270+
firstUsernetIndex := limayaml.FirstUsernetIndex(a.y)
271+
if firstUsernetIndex == -1 && *a.y.HostResolver.Enabled {
271272
hosts := a.y.HostResolver.Hosts
272273
hosts["host.lima.internal"] = networks.SlirpGateway
273274
hosts[fmt.Sprintf("lima-%s", a.instName)] = networks.SlirpIPAddress

pkg/networks/config_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func TestFillDefault(t *testing.T) {
1515
userNet := newYaml.Networks[ModeUserV2]
1616
assert.Equal(t, userNet.Mode, ModeUserV2)
1717
assert.Equal(t, userNet.Interface, "")
18-
assert.DeepEqual(t, userNet.NetMask, net.IP{})
19-
assert.DeepEqual(t, userNet.Gateway, net.IP{})
18+
assert.DeepEqual(t, userNet.NetMask, net.ParseIP("255.255.255.0"))
19+
assert.DeepEqual(t, userNet.Gateway, net.ParseIP("192.168.104.1"))
2020
assert.DeepEqual(t, userNet.DHCPEnd, net.IP{})
2121
}

pkg/networks/const.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@ const (
55
// CIDR is intentionally hardcoded to 192.168.5.0/24, as each of QEMU has its own independent slirp network.
66
SlirpNetwork = "192.168.5.0/24"
77
SlirpGateway = "192.168.5.2"
8-
SlirpDNS = "192.168.5.3"
98
SlirpIPAddress = "192.168.5.15"
109
)

0 commit comments

Comments
 (0)