-/* $OpenBSD: config.c,v 1.60 2021/03/19 09:29:33 kn Exp $ */
+/* $OpenBSD: config.c,v 1.61 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
char base[PATH_MAX];
unsigned int unit;
struct timeval tv, rate, since_last;
+ struct vmop_addr_req var;
errno = 0;
proc_compose_imsg(ps, PROC_VMM, -1,
IMSG_VMDOP_START_VM_IF, vm->vm_vmid, tapfds[i],
&i, sizeof(i));
+
+ memset(&var, 0, sizeof(var));
+ var.var_vmid = vm->vm_vmid;
+ var.var_nic_idx = i;
+ proc_compose_imsg(ps, PROC_PRIV, -1, IMSG_VMDOP_PRIV_GET_ADDR,
+ vm->vm_vmid, dup(tapfds[i]), &var, sizeof(var));
}
if (!(vm->vm_state & VM_STATE_RECEIVED))
-/* $OpenBSD: dhcp.c,v 1.8 2018/12/27 19:51:30 anton Exp $ */
+/* $OpenBSD: dhcp.c,v 1.9 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2017 Reyk Floeter <reyk@openbsd.org>
if ((offset = decode_hw_header(buf, buflen, 0, &pc, HTYPE_ETHER)) < 0)
return (-1);
- if (memcmp(pc.pc_smac, dev->mac, ETHER_ADDR_LEN) != 0 ||
- memcmp(pc.pc_dmac, broadcast, ETHER_ADDR_LEN) != 0)
+ if (memcmp(pc.pc_dmac, broadcast, ETHER_ADDR_LEN) != 0 &&
+ memcmp(pc.pc_dmac, dev->hostmac, ETHER_ADDR_LEN) != 0)
+ return (-1);
+
+ if (memcmp(pc.pc_smac, dev->mac, ETHER_ADDR_LEN) != 0)
return (-1);
if ((offset = decode_udp_ip_header(buf, buflen, offset, &pc)) < 0)
-/* $OpenBSD: priv.c,v 1.16 2021/02/28 22:56:09 dlg Exp $ */
+/* $OpenBSD: priv.c,v 1.17 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
struct ifaliasreq ifra;
struct in6_aliasreq in6_ifra;
struct if_afreq ifar;
+ struct vmop_addr_req vareq;
+ struct vmop_addr_result varesult;
char type[IF_NAMESIZE];
switch (imsg->hdr.type) {
break;
case IMSG_VMDOP_CONFIG:
case IMSG_CTL_RESET:
+ case IMSG_VMDOP_PRIV_GET_ADDR:
break;
default:
return (-1);
if (ioctl(env->vmd_fd6, SIOCAIFADDR_IN6, &in6_ifra) == -1)
log_warn("SIOCAIFADDR_IN6");
break;
+ case IMSG_VMDOP_PRIV_GET_ADDR:
+ IMSG_SIZE_CHECK(imsg, &vareq);
+ memcpy(&vareq, imsg->data, sizeof(vareq));
+
+ varesult.var_vmid = vareq.var_vmid;
+ varesult.var_nic_idx = vareq.var_nic_idx;
+
+ /* resolve lladdr for the tap(4) and send back to parent */
+ if (ioctl(imsg->fd, SIOCGIFADDR, &varesult.var_addr) != 0)
+ log_warn("SIOCGIFADDR");
+ else
+ proc_compose_imsg(ps, PROC_PARENT, -1,
+ IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE, imsg->hdr.peerid,
+ -1, &varesult, sizeof(varesult));
+ close(imsg->fd);
+ break;
case IMSG_VMDOP_CONFIG:
config_getconfig(env, imsg);
break;
-/* $OpenBSD: virtio.c,v 1.83 2021/03/26 17:40:03 deraadt Exp $ */
+/* $OpenBSD: virtio.c,v 1.84 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
evtimer_set(&vmmci.timeout, vmmci_timeout, NULL);
}
+/*
+ * vionet_set_hostmac
+ *
+ * Sets the hardware address for the host-side tap(4) on a vionet_dev.
+ *
+ * This should only be called from the event-loop thread
+ *
+ * vm: pointer to the current vmd_vm instance
+ * idx: index into the array of vionet_dev's for the target vionet_dev
+ * addr: ethernet address to set
+ */
+void
+vionet_set_hostmac(struct vmd_vm *vm, unsigned int idx, uint8_t *addr)
+{
+ struct vmop_create_params *vmc = &vm->vm_params;
+ struct vm_create_params *vcp = &vmc->vmc_params;
+ struct vionet_dev *dev;
+
+ if (idx > vcp->vcp_nnics)
+ fatalx("vionet_set_hostmac");
+
+ dev = &vionet[idx];
+ memcpy(dev->hostmac, addr, sizeof(dev->hostmac));
+}
+
void
virtio_shutdown(struct vmd_vm *vm)
{
-/* $OpenBSD: virtio.h,v 1.36 2021/01/07 17:11:38 tracey Exp $ */
+/* $OpenBSD: virtio.h,v 1.37 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
uint32_t vm_vmid;
int irq;
uint8_t mac[6];
+ uint8_t hostmac[6];
int idx;
int lockedmac;
int vionet_notify_tx(struct vionet_dev *);
void vionet_process_rx(uint32_t);
int vionet_enq_rx(struct vionet_dev *, char *, ssize_t, int *);
+void vionet_set_hostmac(struct vmd_vm *, unsigned int, uint8_t *);
int vmmci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
int vmmci_dump(int);
-/* $OpenBSD: vm.c,v 1.60 2021/03/19 09:29:33 kn Exp $ */
+/* $OpenBSD: vm.c,v 1.61 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
{
struct vmd_vm *vm = arg;
struct vmop_result vmr;
+ struct vmop_addr_result var;
struct imsgev *iev = &vm->vm_iev;
struct imsgbuf *ibuf = &iev->ibuf;
struct imsg imsg;
_exit(0);
}
break;
+ case IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE:
+ IMSG_SIZE_CHECK(&imsg, &var);
+ memcpy(&var, imsg.data, sizeof(var));
+
+ log_debug("%s: received tap addr %s for nic %d",
+ vm->vm_params.vmc_params.vcp_name,
+ ether_ntoa((void *)var.var_addr), var.var_nic_idx);
+
+ vionet_set_hostmac(vm, var.var_nic_idx, var.var_addr);
+ break;
default:
fatalx("%s: got invalid imsg %d from %s",
__func__, imsg.hdr.type,
-/* $OpenBSD: vmd.c,v 1.120 2021/01/27 07:21:54 deraadt Exp $ */
+/* $OpenBSD: vmd.c,v 1.121 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
int vmd_control_run(void);
int vmd_dispatch_control(int, struct privsep_proc *, struct imsg *);
int vmd_dispatch_vmm(int, struct privsep_proc *, struct imsg *);
+int vmd_dispatch_priv(int, struct privsep_proc *, struct imsg *);
int vmd_check_vmh(struct vm_dump_header *);
int vm_instance(struct privsep *, struct vmd_vm **,
static struct privsep_proc procs[] = {
/* Keep "priv" on top as procs[0] */
- { "priv", PROC_PRIV, NULL, priv },
+ { "priv", PROC_PRIV, vmd_dispatch_priv, priv },
{ "control", PROC_CONTROL, vmd_dispatch_control, control },
{ "vmm", PROC_VMM, vmd_dispatch_vmm, vmm, vmm_shutdown },
};
return (0);
}
+int
+vmd_dispatch_priv(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+ struct vmop_addr_result var;
+
+ switch (imsg->hdr.type) {
+ case IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE:
+ IMSG_SIZE_CHECK(imsg, &var);
+ memcpy(&var, imsg->data, sizeof(var));
+ proc_forward_imsg(p->p_ps, imsg, PROC_VMM, -1);
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
int
vmd_check_vmh(struct vm_dump_header *vmh)
{
-/* $OpenBSD: vmd.h,v 1.102 2021/03/19 09:29:33 kn Exp $ */
+/* $OpenBSD: vmd.h,v 1.103 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
IMSG_VMDOP_PRIV_IFADDR,
IMSG_VMDOP_PRIV_IFADDR6,
IMSG_VMDOP_PRIV_IFRDOMAIN,
+ IMSG_VMDOP_PRIV_GET_ADDR,
+ IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE,
IMSG_VMDOP_VM_SHUTDOWN,
IMSG_VMDOP_VM_REBOOT,
IMSG_VMDOP_CONFIG,
struct sockaddr_storage vfr_mask;
};
+struct vmop_addr_req {
+ uint32_t var_vmid;
+ unsigned int var_nic_idx;
+};
+
+struct vmop_addr_result {
+ uint32_t var_vmid;
+ unsigned int var_nic_idx;
+ uint8_t var_addr[ETHER_ADDR_LEN];
+};
+
struct vmop_owner {
uid_t uid;
int64_t gid;
-/* $OpenBSD: vmm.c,v 1.97 2021/03/02 02:56:22 jsg Exp $ */
+/* $OpenBSD: vmm.c,v 1.98 2021/03/29 23:37:01 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
struct vmop_id vid;
struct vmop_result vmr;
struct vmop_create_params vmc;
+ struct vmop_addr_result var;
uint32_t id = 0, peerid = imsg->hdr.peerid;
pid_t pid = 0;
unsigned int mode, flags;
res = ENOENT;
cmd = IMSG_VMDOP_START_VM_RESPONSE;
break;
+ case IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE:
+ IMSG_SIZE_CHECK(imsg, &var);
+ memcpy(&var, imsg->data, sizeof(var));
+ if ((vm = vm_getbyvmid(var.var_vmid)) == NULL) {
+ res = ENOENT;
+ break;
+ }
+ /* Forward hardware address details to the guest vm */
+ imsg_compose_event(&vm->vm_iev,
+ imsg->hdr.type, imsg->hdr.peerid, imsg->hdr.pid,
+ imsg->fd, &var, sizeof(var));
+ break;
default:
return (-1);
}