diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2016-10-15 14:02:12 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2016-10-15 14:02:12 +0000 |
commit | 292c565361f454d97f36299330e6c09b022f1a70 (patch) | |
tree | 0911db0b6d3a5305d15bce4784734f1771869af9 /usr.sbin/vmd | |
parent | 9e02ba4f8bb7e5a75f9b4d21173940a2dcb2c4ca (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.c | 13 | ||||
-rw-r--r-- | usr.sbin/vmd/parse.y | 19 | ||||
-rw-r--r-- | usr.sbin/vmd/priv.c | 42 | ||||
-rw-r--r-- | usr.sbin/vmd/vm.conf.5 | 13 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.c | 3 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.h | 8 |
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 *); |