diff --git a/sys/dev/virtual/vkernel/net/if_vke.c b/sys/dev/virtual/vkernel/net/if_vke.c index 66ae46e..991ee37 100644 --- a/sys/dev/virtual/vkernel/net/if_vke.c +++ b/sys/dev/virtual/vkernel/net/if_vke.c @@ -679,37 +679,52 @@ vke_attach(const struct vknetif_info *info, int unit) struct tapinfo tapinfo; uint8_t enaddr[ETHER_ADDR_LEN]; int fd; + struct ether_addr ethaddr; + int needmac; KKASSERT(info->tap_fd >= 0); fd = info->tap_fd; + needmac = 1; /* - * This is only a TAP device if tap_unit is non-zero. If - * connecting to a virtual socket we generate a unique MAC. + * Copy the ethernet address from userland where it + * was already parsed. */ - 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 (info->eap) { + copyin(info->eap, ðaddr, sizeof(ethaddr)); + bcopy(ethaddr.octet, enaddr, sizeof(ethaddr)); + needmac = 0; + } - 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 (needmac) { + /* + * 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; + } + 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..f1a3962 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; + struct ether_addr *eap; }; struct vkdisk_info { diff --git a/sys/platform/vkernel64/platform/init.c b/sys/platform/vkernel64/platform/init.c index 2b0ca2d..ccfdc1c 100644 --- a/sys/platform/vkernel64/platform/init.c +++ b/sys/platform/vkernel64/platform/init.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -1178,6 +1179,7 @@ void init_netif(char *netifExp[], int netifExpNum) { int i, s; + char *tmp; if (netifExpNum == 0) return; @@ -1192,6 +1194,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 +1233,15 @@ 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) { + info->eap = malloc(sizeof(*info->eap)); + if (info->eap != NULL) + if ((kether_aton(tmp, info->eap->octet)) == NULL) + info->eap = NULL; + } NetifNum++; if (NetifNum >= VKNETIF_MAX) /* XXX will this happen? */