summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2017-04-21 07:03:27 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2017-04-21 07:03:27 +0000
commit85ba50b4aa3962a65d582b9fe82ef52b82792c06 (patch)
treec5c8e4324c71436b718d1c24a47b37b554c6c26b
parentb205e7a4aa0d0df503e8a11788cfa763427ef280 (diff)
Add global configuration option "local prefix" to change prefix for -L.
The default prefix is 100.64.0.0/10 from RFC6598. Requested by sthen@ chris@ OK mlarkin@
-rw-r--r--usr.sbin/vmd/config.c35
-rw-r--r--usr.sbin/vmd/control.c9
-rw-r--r--usr.sbin/vmd/dhcp.c9
-rw-r--r--usr.sbin/vmd/parse.y62
-rw-r--r--usr.sbin/vmd/priv.c27
-rw-r--r--usr.sbin/vmd/vm.conf.522
-rw-r--r--usr.sbin/vmd/vmd.c10
-rw-r--r--usr.sbin/vmd/vmd.h28
-rw-r--r--usr.sbin/vmd/vmm.c5
9 files changed, 181 insertions, 26 deletions
diff --git a/usr.sbin/vmd/config.c b/usr.sbin/vmd/config.c
index 05c3bfc1dab..f100c7b8aa5 100644
--- a/usr.sbin/vmd/config.c
+++ b/usr.sbin/vmd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.29 2017/03/26 18:32:39 reyk Exp $ */
+/* $OpenBSD: config.c,v 1.30 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -50,7 +50,9 @@ config_init(struct vmd *env)
/* Global configuration */
ps->ps_what[PROC_PARENT] = CONFIG_ALL;
ps->ps_what[PROC_VMM] = CONFIG_VMS;
- ps->ps_what[PROC_PRIV] = 0;
+
+ if (host(VMD_DHCP_PREFIX, &env->vmd_cfg.cfg_localprefix) == -1)
+ return (-1);
/* Other configuration */
what = ps->ps_what[privsep_process];
@@ -77,6 +79,10 @@ config_purge(struct vmd *env, unsigned int reset)
struct vmd_switch *vsw;
unsigned int what;
+ /* Reset global configuration (prefix was verified before) */
+ (void)host(VMD_DHCP_PREFIX, &env->vmd_cfg.cfg_localprefix);
+
+ /* Reset other configuration */
what = ps->ps_what[privsep_process] & reset;
if (what & CONFIG_VMS && env->vmd_vms != NULL) {
while ((vm = TAILQ_FIRST(env->vmd_vms)) != NULL)
@@ -91,6 +97,31 @@ config_purge(struct vmd *env, unsigned int reset)
}
int
+config_setconfig(struct vmd *env)
+{
+ struct privsep *ps = &env->vmd_ps;
+ unsigned int id;
+
+ for (id = 0; id < PROC_MAX; id++) {
+ if (id == privsep_process)
+ continue;
+ proc_compose(ps, id, IMSG_VMDOP_CONFIG, &env->vmd_cfg,
+ sizeof(env->vmd_cfg));
+ }
+
+ return (0);
+}
+
+int
+config_getconfig(struct vmd *env, struct imsg *imsg)
+{
+ IMSG_SIZE_CHECK(imsg, &env->vmd_cfg);
+ memcpy(&env->vmd_cfg, imsg->data, sizeof(env->vmd_cfg));
+
+ return (0);
+}
+
+int
config_setreset(struct vmd *env, unsigned int reset)
{
struct privsep *ps = &env->vmd_ps;
diff --git a/usr.sbin/vmd/control.c b/usr.sbin/vmd/control.c
index 2f3d0d9e74b..cb890ca6826 100644
--- a/usr.sbin/vmd/control.c
+++ b/usr.sbin/vmd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.16 2017/03/15 12:42:12 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.17 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org>
@@ -79,6 +79,7 @@ int
control_dispatch_vmd(int fd, struct privsep_proc *p, struct imsg *imsg)
{
struct ctl_conn *c;
+ struct privsep *ps = p->p_ps;
switch (imsg->hdr.type) {
case IMSG_VMDOP_START_VM_RESPONSE:
@@ -93,6 +94,12 @@ control_dispatch_vmd(int fd, struct privsep_proc *p, struct imsg *imsg)
imsg_compose_event(&c->iev, imsg->hdr.type,
0, 0, -1, imsg->data, IMSG_DATA_SIZE(imsg));
break;
+ case IMSG_VMDOP_CONFIG:
+ config_getconfig(ps->ps_env, imsg);
+ break;
+ case IMSG_CTL_RESET:
+ config_getreset(ps->ps_env, imsg);
+ break;
default:
return (-1);
}
diff --git a/usr.sbin/vmd/dhcp.c b/usr.sbin/vmd/dhcp.c
index b8b05000e3a..65ea4ffae33 100644
--- a/usr.sbin/vmd/dhcp.c
+++ b/usr.sbin/vmd/dhcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcp.c,v 1.1 2017/04/19 15:38:32 reyk Exp $ */
+/* $OpenBSD: dhcp.c,v 1.2 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2017 Reyk Floeter <reyk@openbsd.org>
@@ -33,6 +33,7 @@
#include "virtio.h"
static const uint8_t broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+extern struct vmd *env;
ssize_t
dhcp_request(struct vionet_dev *dev, char *buf, size_t buflen, char **obuf)
@@ -81,13 +82,15 @@ dhcp_request(struct vionet_dev *dev, char *buf, size_t buflen, char **obuf)
resp.hlen = req.hlen;
resp.xid = req.xid;
- if ((in.s_addr = vm_priv_addr(dev->vm_vmid, dev->idx, 1)) == 0)
+ if ((in.s_addr = vm_priv_addr(&env->vmd_cfg.cfg_localprefix,
+ dev->vm_vmid, dev->idx, 1)) == 0)
return (-1);
memcpy(&resp.yiaddr, &in, sizeof(in));
memcpy(&ss2sin(&pc.pc_dst)->sin_addr, &in, sizeof(in));
ss2sin(&pc.pc_dst)->sin_port = htons(CLIENT_PORT);
- if ((in.s_addr = vm_priv_addr(dev->vm_vmid, dev->idx, 0)) == 0)
+ if ((in.s_addr = vm_priv_addr(&env->vmd_cfg.cfg_localprefix,
+ dev->vm_vmid, dev->idx, 0)) == 0)
return (-1);
memcpy(&resp.siaddr, &in, sizeof(in));
memcpy(&ss2sin(&pc.pc_src)->sin_addr, &in, sizeof(in));
diff --git a/usr.sbin/vmd/parse.y b/usr.sbin/vmd/parse.y
index cf181701ada..6b35f95a37c 100644
--- a/usr.sbin/vmd/parse.y
+++ b/usr.sbin/vmd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.25 2017/04/19 15:38:32 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.26 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2007-2016 Reyk Floeter <reyk@openbsd.org>
@@ -116,7 +116,7 @@ typedef struct {
%token INCLUDE ERROR
%token ADD DISK DOWN GROUP INTERFACE NIFS PATH SIZE SWITCH UP VMID
-%token ENABLE DISABLE VM BOOT LLADDR MEMORY OWNER LOCKED LOCAL
+%token ENABLE DISABLE VM BOOT LLADDR MEMORY OWNER LOCKED LOCAL PREFIX
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.number> disable
@@ -134,6 +134,7 @@ grammar : /* empty */
| grammar include '\n'
| grammar '\n'
| grammar varset '\n'
+ | grammar main '\n'
| grammar switch '\n'
| grammar vm '\n'
| grammar error '\n' { file->errors++; }
@@ -170,6 +171,22 @@ varset : STRING '=' STRING {
}
;
+main : LOCAL PREFIX STRING {
+ struct address h;
+
+ /* The local prefix is IPv4-only */
+ if (host($3, &h) == -1 ||
+ h.ss.ss_family != AF_INET ||
+ h.prefixlen > 32 || h.prefixlen < 0) {
+ yyerror("invalid local prefix: %s", $3);
+ free($3);
+ YYERROR;
+ }
+
+ memcpy(&env->vmd_cfg.cfg_localprefix, &h, sizeof(h));
+ }
+ ;
+
switch : SWITCH string {
if ((vsw = calloc(1, sizeof(*vsw))) == NULL)
fatal("could not allocate switch");
@@ -627,6 +644,7 @@ lookup(char *s)
{ "locked", LOCKED },
{ "memory", MEMORY },
{ "owner", OWNER },
+ { "prefix", PREFIX },
{ "size", SIZE },
{ "switch", SWITCH },
{ "up", UP },
@@ -1094,3 +1112,43 @@ parse_disk(char *word)
return (0);
}
+
+int
+host(const char *str, struct address *h)
+{
+ struct addrinfo hints, *res;
+ int prefixlen;
+ char *s, *p;
+ const char *errstr;
+
+ if ((s = strdup(str)) == NULL) {
+ log_warn("strdup");
+ goto fail;
+ }
+
+ if ((p = strrchr(s, '/')) != NULL) {
+ *p++ = '\0';
+ prefixlen = strtonum(p, 0, 128, &errstr);
+ if (errstr) {
+ log_warnx("prefixlen is %s: %s", errstr, p);
+ goto fail;
+ }
+ } else
+ prefixlen = 128;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(s, NULL, &hints, &res) == 0) {
+ memset(h, 0, sizeof(*h));
+ memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
+ h->prefixlen = prefixlen;
+ freeaddrinfo(res);
+ free(s);
+ return (0);
+ }
+
+ fail:
+ free(s);
+ return (-1);
+}
diff --git a/usr.sbin/vmd/priv.c b/usr.sbin/vmd/priv.c
index c0f1c36fd25..a1e6414cf6b 100644
--- a/usr.sbin/vmd/priv.c
+++ b/usr.sbin/vmd/priv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: priv.c,v 1.7 2017/04/19 15:38:32 reyk Exp $ */
+/* $OpenBSD: priv.c,v 1.8 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
@@ -102,6 +102,9 @@ priv_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
fatalx("%s: rejected priv operation on interface: %s",
__func__, vfr.vfr_name);
break;
+ case IMSG_VMDOP_CONFIG:
+ case IMSG_CTL_RESET:
+ break;
default:
return (-1);
}
@@ -183,6 +186,12 @@ priv_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
if (ioctl(env->vmd_fd, SIOCAIFADDR, &ifra) < 0)
log_warn("SIOCAIFADDR");
break;
+ case IMSG_VMDOP_CONFIG:
+ config_getconfig(env, imsg);
+ break;
+ case IMSG_CTL_RESET:
+ config_getreset(env, imsg);
+ break;
default:
return (-1);
}
@@ -245,6 +254,7 @@ priv_validgroup(const char *name)
int
vm_priv_ifconfig(struct privsep *ps, struct vmd_vm *vm)
{
+ struct vmd *env = ps->ps_env;
struct vm_create_params *vcp = &vm->vm_params.vmc_params;
struct vmd_if *vif;
struct vmd_switch *vsw;
@@ -333,7 +343,8 @@ vm_priv_ifconfig(struct privsep *ps, struct vmd_vm *vm)
sin4->sin_family = AF_INET;
sin4->sin_len = sizeof(*sin4);
if ((sin4->sin_addr.s_addr =
- vm_priv_addr(vm->vm_vmid, i, 0)) == 0)
+ vm_priv_addr(&env->vmd_cfg.cfg_localprefix,
+ vm->vm_vmid, i, 0)) == 0)
return (-1);
log_debug("%s: interface %s address %s/31",
@@ -393,16 +404,18 @@ vm_priv_brconfig(struct privsep *ps, struct vmd_switch *vsw)
}
uint32_t
-vm_priv_addr(uint32_t vmid, int idx, int isvm)
+vm_priv_addr(struct address *h, uint32_t vmid, int idx, int isvm)
{
- in_addr_t prefix, mask, addr;
+ in_addr_t prefix, mask, addr;
/*
* 1. Set the address prefix and mask, 100.64.0.0/10 by default.
- * XXX make the global prefix configurable.
*/
- prefix = inet_addr(VMD_DHCP_PREFIX);
- mask = prefixlen2mask(VMD_DHCP_PREFIXLEN);
+ if (h->ss.ss_family != AF_INET ||
+ h->prefixlen < 0 || h->prefixlen > 32)
+ fatal("local prefix");
+ prefix = ss2sin(&h->ss)->sin_addr.s_addr;
+ mask = prefixlen2mask(h->prefixlen);
/* 2. Encode the VM ID as a per-VM subnet range N, 10.64.N.0/24. */
addr = vmid << 8;
diff --git a/usr.sbin/vmd/vm.conf.5 b/usr.sbin/vmd/vm.conf.5
index ad610b30b8a..e1dd3997005 100644
--- a/usr.sbin/vmd/vm.conf.5
+++ b/usr.sbin/vmd/vm.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vm.conf.5,v 1.18 2017/04/19 15:38:32 reyk Exp $
+.\" $OpenBSD: vm.conf.5,v 1.19 2017/04/21 07:03:26 reyk Exp $
.\"
.\" Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
.\" Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -15,7 +15,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 19 2017 $
+.Dd $Mdocdate: April 21 2017 $
.Dt VM.CONF 5
.Os
.Sh NAME
@@ -31,11 +31,14 @@ The VMM subsystem is responsible for creating, destroying, and
executing VMs.
.Sh SECTIONS
.Nm
-is divided into three main sections:
+is divided into four main sections:
.Bl -tag -width xxxx
.It Sy Macros
User-defined variables may be defined and used later, simplifying the
configuration file.
+.It Sy Global Configuration
+Global settings for
+.Xr vmd 8 .
.It Sy VM Configuration
Configuration for each individual virtual machine.
.It Sy Switch Configuration
@@ -85,6 +88,19 @@ vm "vm1.example.com" {
boot $ramdisk
}
.Ed
+.Sh GLOBAL CONFIGURATION
+The following setting can be configured globally:
+.Bl -tag -width Ds
+.It Ic local prefix Ar address Ns Li / Ns Ar prefix
+Set the network prefix that is used to allocate subnets for
+local interfaces, see
+.Ic local interface
+in the
+.Sx VM CONFIGURATION
+section below.
+The default is
+.Ar 100.64.0.0/10 .
+.El
.Sh VM CONFIGURATION
Each
.Ic vm
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index fcd2c3696b9..65918419b3b 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.57 2017/04/19 15:38:32 reyk Exp $ */
+/* $OpenBSD: vmd.c,v 1.58 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -562,6 +562,10 @@ vmd_configure(void)
return (-1);
}
+ /* Send shared global configuration to all children */
+ if (config_setconfig(env) == -1)
+ return (-1);
+
return (0);
}
@@ -598,6 +602,10 @@ vmd_reload(unsigned int reset, const char *filename)
if (vm->vm_running == 0)
vm_remove(vm);
}
+
+ /* Update shared global configuration in all children */
+ if (config_setconfig(env) == -1)
+ return;
}
if (parse_config(filename) == -1) {
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 5dc0bb4d81d..0846dbb6436 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.51 2017/04/19 15:38:32 reyk Exp $ */
+/* $OpenBSD: vmd.h,v 1.52 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -51,8 +51,7 @@
#define VM_DEFAULT_MEMORY 512
/* 100.64.0.0/10 from rfc6598 (IPv4 Prefix for Shared Address Space) */
-#define VMD_DHCP_PREFIX "100.64.0.0"
-#define VMD_DHCP_PREFIXLEN 10
+#define VMD_DHCP_PREFIX "100.64.0.0/10"
#ifdef VMD_DEBUG
#define dprintf(x...) do { log_debug(x); } while(0)
@@ -82,7 +81,8 @@ enum imsg_type {
IMSG_VMDOP_PRIV_IFGROUP,
IMSG_VMDOP_PRIV_IFADDR,
IMSG_VMDOP_VM_SHUTDOWN,
- IMSG_VMDOP_VM_REBOOT
+ IMSG_VMDOP_VM_REBOOT,
+ IMSG_VMDOP_CONFIG
};
struct vmop_result {
@@ -189,17 +189,30 @@ struct vmd_vm {
};
TAILQ_HEAD(vmlist, vmd_vm);
+struct address {
+ struct sockaddr_storage ss;
+ int prefixlen;
+ TAILQ_ENTRY(address) entry;
+};
+TAILQ_HEAD(addresslist, address);
+
+struct vmd_config {
+ struct address cfg_localprefix;
+};
+
struct vmd {
struct privsep vmd_ps;
const char *vmd_conffile;
+ /* global configuration that is sent to the children */
+ struct vmd_config vmd_cfg;
+
int vmd_debug;
int vmd_verbose;
int vmd_noaction;
uint32_t vmd_nvm;
struct vmlist *vmd_vms;
-
uint32_t vmd_nswitches;
struct switchlist *vmd_switches;
@@ -266,7 +279,7 @@ int priv_findname(const char *, const char **);
int priv_validgroup(const char *);
int vm_priv_ifconfig(struct privsep *, struct vmd_vm *);
int vm_priv_brconfig(struct privsep *, struct vmd_switch *);
-uint32_t vm_priv_addr(uint32_t, int, int);
+uint32_t vm_priv_addr(struct address *, uint32_t, int, int);
/* vmm.c */
void vmm(struct privsep *, struct privsep_proc *);
@@ -286,6 +299,8 @@ __dead void vm_shutdown(unsigned int);
/* control.c */
int config_init(struct vmd *);
void config_purge(struct vmd *, unsigned int);
+int config_setconfig(struct vmd *);
+int config_getconfig(struct vmd *, struct imsg *);
int config_setreset(struct vmd *, unsigned int);
int config_getreset(struct vmd *, struct imsg *);
int config_setvm(struct privsep *, struct vmd_vm *, uint32_t, uid_t);
@@ -300,5 +315,6 @@ void vmboot_close(FILE *, struct vmboot_params *);
/* parse.y */
int parse_config(const char *);
int cmdline_symset(char *);
+int host(const char *, struct address *);
#endif /* VMD_H */
diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c
index f0ba6d9ac3e..3b0a453032b 100644
--- a/usr.sbin/vmd/vmm.c
+++ b/usr.sbin/vmd/vmm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm.c,v 1.68 2017/04/06 18:07:13 reyk Exp $ */
+/* $OpenBSD: vmm.c,v 1.69 2017/04/21 07:03:26 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -175,6 +175,9 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
res = get_info_vm(ps, imsg, 0);
cmd = IMSG_VMDOP_GET_INFO_VM_END_DATA;
break;
+ case IMSG_VMDOP_CONFIG:
+ config_getconfig(env, imsg);
+ break;
case IMSG_CTL_RESET:
IMSG_SIZE_CHECK(imsg, &mode);
memcpy(&mode, imsg->data, sizeof(mode));