From 923ce6da9a97e870813201b5f5f266e32187d7ec Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Wed, 19 Apr 2017 15:38:33 +0000 Subject: Add support for dynamic "NAT" interfaces (-L/local interface). When a local interface is configured, vmd configures a /31 address on the tap(4) interface of the host and provides another IP in the same subnet via DHCP (BOOTP) to the VM. vmd runs an internal BOOTP server that replies with IP, gateway, and DNS addresses to the VM. The built-in server only ever responds to the VM on the inside and cannot leak its DHCP responses to the outside. Thanks to Uwe Werler, Josh Grosse, and some others for testing! OK deraadt@ --- usr.sbin/vmctl/main.c | 10 +++++++--- usr.sbin/vmctl/vmctl.8 | 12 +++++++++--- usr.sbin/vmctl/vmctl.c | 12 ++++++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) (limited to 'usr.sbin/vmctl') diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c index da27fd6c913..20ced9884e7 100644 --- a/usr.sbin/vmctl/main.c +++ b/usr.sbin/vmctl/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.25 2017/04/06 18:07:13 reyk Exp $ */ +/* $OpenBSD: main.c,v 1.26 2017/04/19 15:38:32 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -65,7 +65,7 @@ struct ctl_command ctl_commands[] = { { "reload", CMD_RELOAD, ctl_reload, "" }, { "reset", CMD_RESET, ctl_reset, "[all|vms|switches]" }, { "start", CMD_START, ctl_start, "\"name\"" - " [-c] [-b image] [-m size]\n" + " [-Lc] [-b image] [-m size]\n" "\t\t[-n switch] [-i count] [-d disk]*" }, { "status", CMD_STATUS, ctl_status, "[id]" }, { "stop", CMD_STOP, ctl_stop, "id" }, @@ -539,7 +539,7 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) argc--; argv++; - while ((ch = getopt(argc, argv, "b:cm:n:d:i:")) != -1) { + while ((ch = getopt(argc, argv, "b:cLm:n:d:i:")) != -1) { switch (ch) { case 'b': if (res->path) @@ -552,6 +552,10 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) case 'c': tty_autoconnect = 1; break; + case 'L': + if (parse_network(res, ".") != 0) + errx(1, "invalid network: %s", optarg); + break; case 'm': if (res->size) errx(1, "memory specified multiple times"); diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8 index aed2816f15f..71a0aa4e7f6 100644 --- a/usr.sbin/vmctl/vmctl.8 +++ b/usr.sbin/vmctl/vmctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: vmctl.8,v 1.28 2017/04/14 00:53:28 mlarkin Exp $ +.\" $OpenBSD: vmctl.8,v 1.29 2017/04/19 15:38:32 reyk Exp $ .\" .\" Copyright (c) 2015 Mike Larkin .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 14 2017 $ +.Dd $Mdocdate: April 19 2017 $ .Dt VMCTL 8 .Os .Sh NAME @@ -72,8 +72,8 @@ Reset the configured switches. .It Cm reset vms Reset and terminate all VMs. .It Xo Cm start Ar name +.Op Fl Lc .Op Fl b Ar path -.Op Fl c .Op Fl d Ar path .Op Fl i Ar count .Op Fl m Ar size @@ -91,6 +91,12 @@ Automatically connect to the VM console. Disk image file (may be specified multiple times to add multiple disk images). .It Fl i Ar count Number of network interfaces to add to the VM. +.It Fl L +Add a local network interface. +.Xr vmd 8 +will auto-generate an IPv4 subnet for the interface, +configure a gateway address on the VM host side, +and run a simple DHCP (BOOTP) server for the VM. .It Fl m Ar size Memory .Ar size diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c index 39d1615d8f2..ee9c6db0e9d 100644 --- a/usr.sbin/vmctl/vmctl.c +++ b/usr.sbin/vmctl/vmctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.c,v 1.29 2017/04/06 18:07:13 reyk Exp $ */ +/* $OpenBSD: vmctl.c,v 1.30 2017/04/19 15:38:32 reyk Exp $ */ /* * Copyright (c) 2014 Mike Larkin @@ -123,8 +123,16 @@ vm_start(uint32_t start_id, const char *name, int memsize, int nnics, for (i = 0 ; i < ndisks; i++) strlcpy(vcp->vcp_disks[i], disks[i], VMM_MAX_PATH_DISK); for (i = 0 ; i < nnics; i++) { - strlcpy(vmc->vmc_ifswitch[i], nics[i], IF_NAMESIZE); vmc->vmc_ifflags[i] = VMIFF_UP; + + if (strcmp(".", nics[i]) == 0) { + /* Add a "local" interface */ + strlcpy(vmc->vmc_ifswitch[i], "", IF_NAMESIZE); + vmc->vmc_ifflags[i] |= VMIFF_LOCAL; + } else { + /* Add a interface to a switch */ + strlcpy(vmc->vmc_ifswitch[i], nics[i], IF_NAMESIZE); + } } if (name != NULL) strlcpy(vcp->vcp_name, name, VMM_MAX_NAME_LEN); -- cgit v1.2.3