diff --git a/sys/dev/virtual/vkernel/net/if_vke.c b/sys/dev/virtual/vkernel/net/if_vke.c index 66ae46e..54c431c 100644 --- a/sys/dev/virtual/vkernel/net/if_vke.c +++ b/sys/dev/virtual/vkernel/net/if_vke.c @@ -683,33 +683,36 @@ vke_attach(const struct vknetif_info *info, int unit) KKASSERT(info->tap_fd >= 0); fd = info->tap_fd; - /* - * This is only a TAP device if tap_unit is non-zero. If - * connecting to a virtual socket we generate a unique MAC. - */ - if (info->tap_unit >= 0) { - if (ioctl(fd, TAPGIFINFO, &tapinfo) < 0) { - kprintf(VKE_DEVNAME "%d: ioctl(TAPGIFINFO) " - "failed: %s\n", unit, strerror(errno)); - return ENXIO; - } + if ((strcmp(info->ethstr, "needmac") == 0) || + (kether_aton(info->ethstr, enaddr) == NULL)) { + /* + * This is only a TAP device if tap_unit is non-zero. If + * connecting to a virtual socket we generate a unique MAC. + */ + if (info->tap_unit >= 0) { + if (ioctl(fd, TAPGIFINFO, &tapinfo) < 0) { + kprintf(VKE_DEVNAME "%d: ioctl(TAPGIFINFO) " + "failed: %s\n", unit, strerror(errno)); + return ENXIO; + } - if (ioctl(fd, SIOCGIFADDR, enaddr) < 0) { - kprintf(VKE_DEVNAME "%d: ioctl(SIOCGIFADDR) " - "failed: %s\n", unit, strerror(errno)); - return ENXIO; - } - } else { - int fd = open("/dev/urandom", O_RDONLY); - if (fd >= 0) { - read(fd, enaddr + 2, 4); - close(fd); - } - enaddr[4] = (int)getpid() >> 8; - enaddr[5] = (int)getpid() & 255; + if (ioctl(fd, SIOCGIFADDR, enaddr) < 0) { + kprintf(VKE_DEVNAME "%d: ioctl(SIOCGIFADDR) " + "failed: %s\n", unit, strerror(errno)); + return ENXIO; + } + } else { + int fd = open("/dev/urandom", O_RDONLY); + if (fd >= 0) { + read(fd, enaddr + 2, 4); + close(fd); + } + enaddr[4] = (int)getpid() >> 8; + enaddr[5] = (int)getpid() & 255; + } + enaddr[1] += 1; } - enaddr[1] += 1; sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); diff --git a/sys/platform/vkernel/include/md_var.h b/sys/platform/vkernel/include/md_var.h index 2597bf4..4b211b1 100644 --- a/sys/platform/vkernel/include/md_var.h +++ b/sys/platform/vkernel/include/md_var.h @@ -41,6 +41,9 @@ #ifndef _SYS_VKERNEL_H_ #include #endif +#ifndef _NET_ETHERNET_H_ +#include +#endif #define VKNETIF_MAX 16 #define VKDISK_MAX 16 @@ -50,6 +53,7 @@ struct vknetif_info { int tap_unit; in_addr_t netif_addr; in_addr_t netif_mask; + char ethstr[ETHER_ADDRSTRLEN + 1]; }; struct vkdisk_info { diff --git a/sys/platform/vkernel64/include/md_var.h b/sys/platform/vkernel64/include/md_var.h index 286b2fb..affded5 100644 --- a/sys/platform/vkernel64/include/md_var.h +++ b/sys/platform/vkernel64/include/md_var.h @@ -43,6 +43,9 @@ #ifndef _SYS_VKERNEL_H_ #include #endif +#ifndef _NET_ETHERNET_H_ +#include +#endif #define VKNETIF_MAX 16 #define VKDISK_MAX 16 @@ -52,6 +55,7 @@ struct vknetif_info { int tap_unit; in_addr_t netif_addr; in_addr_t netif_mask; + char ethstr[ETHER_ADDRSTRLEN + 1]; }; struct vkdisk_info { diff --git a/sys/platform/vkernel64/platform/init.c b/sys/platform/vkernel64/platform/init.c index 2b0ca2d..00d56bb 100644 --- a/sys/platform/vkernel64/platform/init.c +++ b/sys/platform/vkernel64/platform/init.c @@ -1178,6 +1178,7 @@ void init_netif(char *netifExp[], int netifExpNum) { int i, s; + char *tmp; if (netifExpNum == 0) return; @@ -1192,6 +1193,10 @@ init_netif(char *netifExp[], int netifExpNum) int tap_fd, tap_unit; char *netif; + /* Extract MAC address if there is one */ + tmp = netifExp[i]; + strsep(&tmp, "="); + netif = strtok(netifExp[i], ":"); if (netif == NULL) { warnx("Invalid argument to '-I'"); @@ -1227,6 +1232,13 @@ init_netif(char *netifExp[], int netifExpNum) info->tap_unit = tap_unit; info->netif_addr = netif_addr; info->netif_mask = netif_mask; + /* + * Set our MAC in the case it was correctly passed. + */ + if (tmp != NULL) + strlcpy(info->ethstr, tmp, ETHER_ADDRSTRLEN + 1); + else + strlcpy(info->ethstr, "needmac", 7); NetifNum++; if (NetifNum >= VKNETIF_MAX) /* XXX will this happen? */