summaryrefslogtreecommitdiff
path: root/usr.sbin/vmd
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2016-10-15 14:02:12 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2016-10-15 14:02:12 +0000
commit292c565361f454d97f36299330e6c09b022f1a70 (patch)
tree0911db0b6d3a5305d15bce4784734f1771869af9 /usr.sbin/vmd
parent9e02ba4f8bb7e5a75f9b4d21173940a2dcb2c4ca (diff)
Allow to add an interface to an interface group; with the group keyword.
Requested and tested by martijn@
Diffstat (limited to 'usr.sbin/vmd')
-rw-r--r--usr.sbin/vmd/config.c13
-rw-r--r--usr.sbin/vmd/parse.y19
-rw-r--r--usr.sbin/vmd/priv.c42
-rw-r--r--usr.sbin/vmd/vm.conf.513
-rw-r--r--usr.sbin/vmd/vmd.c3
-rw-r--r--usr.sbin/vmd/vmd.h8
6 files changed, 89 insertions, 9 deletions
diff --git a/usr.sbin/vmd/config.c b/usr.sbin/vmd/config.c
index c9dd9a22314..bda115c6f2d 100644
--- a/usr.sbin/vmd/config.c
+++ b/usr.sbin/vmd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.15 2016/10/12 10:58:32 reyk Exp $ */
+/* $OpenBSD: config.c,v 1.16 2016/10/15 14:02:11 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -272,6 +272,17 @@ config_getvm(struct privsep *ps, struct vmop_create_params *vmc,
}
}
+ /* Check if the the interface is assigned to a group */
+ s = vmc->vmc_ifgroup[i];
+ if (*s != '\0') {
+ if ((vif->vif_group = strdup(s)) == NULL) {
+ saved_errno = errno;
+ log_warn("%s: can't save group",
+ __func__);
+ goto fail;
+ }
+ }
+
/* Set the interface status */
vif->vif_flags = vmc->vmc_ifflags[i] & IFF_UP;
}
diff --git a/usr.sbin/vmd/parse.y b/usr.sbin/vmd/parse.y
index 9984cbac8f9..e6b9916787c 100644
--- a/usr.sbin/vmd/parse.y
+++ b/usr.sbin/vmd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.9 2016/10/05 17:31:22 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.10 2016/10/15 14:02:11 reyk Exp $ */
/*
* Copyright (c) 2007-2016 Reyk Floeter <reyk@openbsd.org>
@@ -108,7 +108,7 @@ typedef struct {
%token INCLUDE ERROR
-%token ADD DISK DOWN INTERFACE NIFS PATH SIZE SWITCH UP VMID
+%token ADD DISK DOWN GROUP INTERFACE NIFS PATH SIZE SWITCH UP VMID
%token ENABLE DISABLE VM KERNEL LLADDR MEMORY
%token <v.string> STRING
%token <v.number> NUMBER
@@ -424,6 +424,20 @@ iface_opts : SWITCH string {
}
free($2);
}
+ | GROUP string {
+ unsigned int i = vcp_nnics;
+
+ if (priv_validgroup($2) == -1) {
+ yyerror("invalid group name: %s", $2);
+ free($2);
+ YYERROR;
+ }
+
+ /* No need to check if the group exists */
+ (void)strlcpy(vmc.vmc_ifgroup[i], $2,
+ sizeof(vmc.vmc_ifgroup[i]));
+ free($2);
+ }
| LLADDR lladdr {
memcpy(vcp->vcp_macs[vcp_nnics], $2, ETHER_ADDR_LEN);
}
@@ -516,6 +530,7 @@ lookup(char *s)
{ "disk", DISK },
{ "down", DOWN },
{ "enable", ENABLE },
+ { "group", GROUP },
{ "id", VMID },
{ "include", INCLUDE },
{ "interface", INTERFACE },
diff --git a/usr.sbin/vmd/priv.c b/usr.sbin/vmd/priv.c
index 65799d0251f..35a1076d043 100644
--- a/usr.sbin/vmd/priv.c
+++ b/usr.sbin/vmd/priv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: priv.c,v 1.2 2016/10/05 17:30:13 reyk Exp $ */
+/* $OpenBSD: priv.c,v 1.3 2016/10/15 14:02:11 reyk Exp $ */
/*
* Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
@@ -37,6 +37,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
+#include <ctype.h>
#include "proc.h"
#include "vmd.h"
@@ -78,6 +79,7 @@ priv_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
struct vmd *env = ps->ps_env;
struct ifreq ifr;
struct ifbreq ifbr;
+ struct ifgroupreq ifgr;
char type[IF_NAMESIZE];
switch (imsg->hdr.type) {
@@ -86,6 +88,7 @@ priv_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_VMDOP_PRIV_IFADD:
case IMSG_VMDOP_PRIV_IFUP:
case IMSG_VMDOP_PRIV_IFDOWN:
+ case IMSG_VMDOP_PRIV_IFGROUP:
IMSG_SIZE_CHECK(imsg, &vfr);
memcpy(&vfr, imsg->data, sizeof(vfr));
@@ -143,6 +146,20 @@ priv_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
if (ioctl(env->vmd_fd, SIOCSIFFLAGS, &ifr) < 0)
log_warn("SIOCSIFFLAGS");
break;
+ case IMSG_VMDOP_PRIV_IFGROUP:
+ if (priv_validgroup(vfr.vfr_value) == -1)
+ fatalx("%s: invalid group name", __func__);
+
+ if (strlcpy(ifgr.ifgr_name, vfr.vfr_name,
+ sizeof(ifgr.ifgr_name)) >= sizeof(ifgr.ifgr_name) ||
+ strlcpy(ifgr.ifgr_group, vfr.vfr_value,
+ sizeof(ifgr.ifgr_group)) >= sizeof(ifgr.ifgr_group))
+ fatalx("%s: group name too long", __func__);
+
+ if (ioctl(env->vmd_fd, SIOCAIFGROUP, &ifgr) < 0 &&
+ errno != EEXIST)
+ log_warn("SIOCAIFGROUP");
+ break;
default:
return (-1);
}
@@ -187,6 +204,17 @@ priv_findname(const char *name, const char **names)
return (-1);
}
+int
+priv_validgroup(const char *name)
+{
+ if (strlen(name) >= IF_NAMESIZE)
+ return (-1);
+ /* Group can not end with a digit */
+ if (name[0] && isdigit(name[strlen(name) - 1]))
+ return (-1);
+ return (0);
+}
+
/*
* Called from the process peer
*/
@@ -220,6 +248,18 @@ vm_priv_ifconfig(struct privsep *ps, struct vmd_vm *vm)
proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFDESCR,
&vfr, sizeof(vfr));
+ if (vif->vif_group) {
+ if (strlcpy(vfr.vfr_value, vif->vif_group,
+ sizeof(vfr.vfr_value)) >= sizeof(vfr.vfr_value))
+ return (-1);
+
+ log_debug("%s: interface %s group %s", __func__,
+ vfr.vfr_name, vfr.vfr_value);
+
+ proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFGROUP,
+ &vfr, sizeof(vfr));
+ }
+
/* Add interface to bridge/switch */
if ((vsw = switch_getbyname(vif->vif_switch)) != NULL) {
if (strlcpy(vfbr.vfr_name, vsw->sw_ifname,
diff --git a/usr.sbin/vmd/vm.conf.5 b/usr.sbin/vmd/vm.conf.5
index adcb175e94d..13b5edfd1b3 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.7 2016/10/06 10:59:14 jmc Exp $
+.\" $OpenBSD: vm.conf.5,v 1.8 2016/10/15 14:02:11 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: October 6 2016 $
+.Dd $Mdocdate: October 15 2016 $
.Dt VM.CONF 5
.Os
.Sh NAME
@@ -125,6 +125,15 @@ interface on the VM host side (the default) or
to select a specific one.
Valid options are:
.Bl -tag -width Ds
+.It Cm group Ar group-name
+Assign the interface to a specific interface
+.Dq group .
+For example, this can be used to write
+.Xr pf.conf 5
+rules for several VM interfaces in the same group.
+The
+.Ar group-name
+must not end with a digit.
.It Cm lladdr Ar etheraddr
Change the link layer address (MAC address) of the interface on the
VM guest side.
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index 056b8dec336..352ac4d6318 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.34 2016/10/12 19:10:03 reyk Exp $ */
+/* $OpenBSD: vmd.c,v 1.35 2016/10/15 14:02:11 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -550,6 +550,7 @@ vm_remove(struct vmd_vm *vm)
close(vm->vm_ifs[i].vif_fd);
free(vm->vm_ifs[i].vif_name);
free(vm->vm_ifs[i].vif_switch);
+ free(vm->vm_ifs[i].vif_group);
}
if (vm->vm_kernel != -1)
close(vm->vm_kernel);
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 5235189ee11..2848a2c72c5 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.29 2016/10/12 19:10:03 reyk Exp $ */
+/* $OpenBSD: vmd.h,v 1.30 2016/10/15 14:02:11 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -66,7 +66,8 @@ enum imsg_type {
IMSG_VMDOP_PRIV_IFADD,
IMSG_VMDOP_PRIV_IFCREATE,
IMSG_VMDOP_PRIV_IFUP,
- IMSG_VMDOP_PRIV_IFDOWN
+ IMSG_VMDOP_PRIV_IFDOWN,
+ IMSG_VMDOP_PRIV_IFGROUP
};
struct vmop_result {
@@ -99,11 +100,13 @@ struct vmop_create_params {
unsigned int vmc_ifflags[VMM_MAX_NICS_PER_VM];
char vmc_ifnames[VMM_MAX_NICS_PER_VM][IF_NAMESIZE];
char vmc_ifswitch[VMM_MAX_NICS_PER_VM][VM_NAME_MAX];
+ char vmc_ifgroup[VMM_MAX_NICS_PER_VM][IF_NAMESIZE];
};
struct vmd_if {
char *vif_name;
char *vif_switch;
+ char *vif_group;
int vif_fd;
unsigned int vif_flags;
TAILQ_ENTRY(vmd_if) vif_entry;
@@ -166,6 +169,7 @@ char *get_string(uint8_t *, size_t);
void priv(struct privsep *, struct privsep_proc *);
int priv_getiftype(char *, char *, unsigned int *);
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 *);