Generate randomized MAC addresses earlier to keep them across reboots.
authorreyk <reyk@openbsd.org>
Tue, 25 Apr 2017 16:38:23 +0000 (16:38 +0000)
committerreyk <reyk@openbsd.org>
Tue, 25 Apr 2017 16:38:23 +0000 (16:38 +0000)
OK deraadt@

usr.sbin/vmd/virtio.c
usr.sbin/vmd/vmd.c

index 5bdb999..f84110a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: virtio.c,v 1.42 2017/04/19 15:38:32 reyk Exp $        */
+/*     $OpenBSD: virtio.c,v 1.43 2017/04/25 16:38:23 reyk Exp $        */
 
 /*
  * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1599,10 +1599,9 @@ virtio_init(struct vmd_vm *vm, int *child_disks, int *child_taps)
 {
        struct vmop_create_params *vmc = &vm->vm_params;
        struct vm_create_params *vcp = &vmc->vmc_params;
-       static const uint8_t zero_mac[6];
        uint8_t id;
        uint8_t i;
-       int ret, rng;
+       int ret;
        off_t sz;
 
        /* Virtio entropy device */
@@ -1738,28 +1737,10 @@ virtio_init(struct vmd_vm *vm, int *child_disks, int *child_taps)
                                return;
                        }
 
+                       /* MAC address has been assigned by the parent */
+                       memcpy(&vionet[i].mac, &vcp->vcp_macs[i], 6);
                        vionet[i].cfg.device_feature = VIRTIO_NET_F_MAC;
 
-                       if (memcmp(zero_mac, &vcp->vcp_macs[i], 6) != 0) {
-                               /* User-defined address */
-                               memcpy(&vionet[i].mac, &vcp->vcp_macs[i], 6);
-                       } else {
-                               /*
-                                * If the address is zero, always randomize
-                                * it in vmd(8) because we cannot rely on
-                                * the guest OS to do the right thing like
-                                * OpenBSD does.  Based on ether_fakeaddr()
-                                * from the kernel, incremented by one to
-                                * differentiate the source.
-                                */
-                               rng = arc4random();
-                               vionet[i].mac[0] = 0xfe;
-                               vionet[i].mac[1] = 0xe1;
-                               vionet[i].mac[2] = 0xba + 1;
-                               vionet[i].mac[3] = 0xd0 | ((i + 1) & 0xf);
-                               vionet[i].mac[4] = rng;
-                               vionet[i].mac[5] = rng >> 8;
-                       }
                        vionet[i].lockedmac =
                            vmc->vmc_ifflags[i] & VMIFF_LOCKED ? 1 : 0;
                        vionet[i].local =
index 6591841..91f387d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmd.c,v 1.58 2017/04/21 07:03:26 reyk Exp $   */
+/*     $OpenBSD: vmd.c,v 1.59 2017/04/25 16:38:23 reyk Exp $   */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -796,6 +796,8 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
 {
        struct vmd_vm           *vm = NULL;
        struct vm_create_params *vcp = &vmc->vmc_params;
+       static const uint8_t     zero_mac[ETHER_ADDR_LEN];
+       uint32_t                 rng;
        unsigned int             i;
        struct vmd_switch       *sw;
 
@@ -851,6 +853,7 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
 
        memcpy(&vm->vm_params, vmc, sizeof(vm->vm_params));
        vmc = &vm->vm_params;
+       vcp = &vmc->vmc_params;
        vm->vm_pid = -1;
        vm->vm_tty = -1;
 
@@ -863,6 +866,23 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
                        /* inherit per-interface flags from the switch */
                        vmc->vmc_ifflags[i] |= (sw->sw_flags & VMIFF_OPTMASK);
                }
+
+               /*
+                * If the MAC address is zero, always randomize it in vmd(8)
+                * because we cannot rely on the guest OS to do the right
+                * thing like OpenBSD does.  Based on ether_fakeaddr()
+                * from the kernel, incremented by one to differentiate
+                * the source.
+                */
+               if (memcmp(zero_mac, &vcp->vcp_macs[i], ETHER_ADDR_LEN) == 0) {
+                       rng = arc4random();
+                       vcp->vcp_macs[i][0] = 0xfe;
+                       vcp->vcp_macs[i][1] = 0xe1;
+                       vcp->vcp_macs[i][2] = 0xba + 1;
+                       vcp->vcp_macs[i][3] = 0xd0 | ((i + 1) & 0xf);
+                       vcp->vcp_macs[i][4] = rng;
+                       vcp->vcp_macs[i][5] = rng >> 8;
+               }
        }
        vm->vm_kernel = -1;
        vm->vm_iev.ibuf.fd = -1;