Skip to content

Commit

Permalink
kola/qemuexec: allow changing guest network
Browse files Browse the repository at this point in the history
This is useful when you're nesting VMs and you want the first VM to
be able to access the host. The default host address that QEMU assigns
(e.g. 10.0.2.2, modifiable via the `host=...` netdev knob) doesn't
always work because it's not actually an IP address owned by the host,
but proxied by QEMU itself.

So the source appears to come from localhost, but in some contexts (e.g.
iSCSI), we need the host and the guest to agree that the same IP refers
to the host.

With this, one can start the first VM as usual (e.g. `cosa run`) and the
second VM within with e.g. `cosa run --usernet-addr 10.0.3.0/24` and be
able to talk back to the outer VM via the valid address 10.0.2.15.

To be clear, this can all be done with passthrough QEMU args, so this is
just about making it more convenient.
  • Loading branch information
jlebon committed Oct 17, 2023
1 parent 87e92d0 commit fd7a277
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 7 deletions.
7 changes: 5 additions & 2 deletions mantle/cmd/kola/qemuexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ var (

netboot string
netbootDir string

usernetAddr string
)

const maxAdditionalNics = 16
Expand Down Expand Up @@ -102,6 +104,7 @@ func init() {
cmdQemuExec.Flags().StringVarP(&sshCommand, "ssh-command", "x", "", "Command to execute instead of spawning a shell")
cmdQemuExec.Flags().StringVarP(&netboot, "netboot", "", "", "Filepath to BOOTP program (e.g. PXELINUX/GRUB binary or iPXE script")
cmdQemuExec.Flags().StringVarP(&netbootDir, "netboot-dir", "", "", "Directory to serve over TFTP (default: BOOTP parent dir). If specified, --netboot is relative to this dir.")
cmdQemuExec.Flags().StringVarP(&usernetAddr, "usernet-addr", "", "", "Guest IP network (QEMU default is '10.0.2.0/24')")
}

func renderFragments(fragments []string, c *conf.Conf) error {
Expand Down Expand Up @@ -356,11 +359,11 @@ func runQemuExec(cmd *cobra.Command, args []string) error {
if cpuCountHost {
builder.Processors = -1
}
if usernet {
if usernet || usernetAddr != "" {
h := []platform.HostForwardPort{
{Service: "ssh", HostPort: 0, GuestPort: 22},
}
builder.EnableUsermodeNetworking(h)
builder.EnableUsermodeNetworking(h, usernetAddr)
}
if netboot != "" {
builder.SetNetbootP(netboot, netbootDir)
Expand Down
4 changes: 2 additions & 2 deletions mantle/platform/machine/qemu/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl
}

if len(options.HostForwardPorts) > 0 {
builder.EnableUsermodeNetworking(options.HostForwardPorts)
builder.EnableUsermodeNetworking(options.HostForwardPorts, "")
} else {
h := []platform.HostForwardPort{
{Service: "ssh", HostPort: 0, GuestPort: 22},
}
builder.EnableUsermodeNetworking(h)
builder.EnableUsermodeNetworking(h, "")
}
if options.AdditionalNics > 0 {
builder.AddAdditionalNics(options.AdditionalNics)
Expand Down
4 changes: 2 additions & 2 deletions mantle/platform/machine/qemuiso/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl
}

if len(options.HostForwardPorts) > 0 {
builder.EnableUsermodeNetworking(options.HostForwardPorts)
builder.EnableUsermodeNetworking(options.HostForwardPorts, "")
} else {
h := []platform.HostForwardPort{
{Service: "ssh", HostPort: 0, GuestPort: 22},
}
builder.EnableUsermodeNetworking(h)
builder.EnableUsermodeNetworking(h, "")
}

if options.AdditionalNics > 0 {
Expand Down
7 changes: 6 additions & 1 deletion mantle/platform/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ type QemuBuilder struct {
ignitionRendered bool

UsermodeNetworking bool
usermodeNetworkingAddr string
RestrictNetworking bool
requestedHostForwardPorts []HostForwardPort
additionalNics int
Expand Down Expand Up @@ -599,9 +600,10 @@ func virtio(arch, device, args string) string {

// EnableUsermodeNetworking configure forwarding for all requested ports,
// via usermode network helpers.
func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort) {
func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort, usernetAddr string) {
builder.UsermodeNetworking = true
builder.requestedHostForwardPorts = h
builder.usermodeNetworkingAddr = usernetAddr
}

func (builder *QemuBuilder) SetNetbootP(filename, dir string) {
Expand Down Expand Up @@ -637,6 +639,9 @@ func (builder *QemuBuilder) setupNetworking() error {
if builder.RestrictNetworking {
netdev += ",restrict=on"
}
if builder.usermodeNetworkingAddr != "" {
netdev += ",net=" + builder.usermodeNetworkingAddr
}
if builder.netbootP != "" {
// do an early stat so we fail with a nicer error now instead of in the VM
if _, err := os.Stat(filepath.Join(builder.netbootDir, builder.netbootP)); err != nil {
Expand Down

0 comments on commit fd7a277

Please sign in to comment.