diff --git a/sys/dev/virtual/vkernel/net/if_vke.c b/sys/dev/virtual/vkernel/net/if_vke.c index 66ae46e..b008ab1 100644 --- a/sys/dev/virtual/vkernel/net/if_vke.c +++ b/sys/dev/virtual/vkernel/net/if_vke.c @@ -700,16 +700,23 @@ vke_attach(const struct vknetif_info *info, int unit) return ENXIO; } } else { - int fd = open("/dev/urandom", O_RDONLY); - if (fd >= 0) { - read(fd, enaddr + 2, 4); - close(fd); + /* + * Convert our MAC string to its hw address representation + * and fall back to pseudo-random MAC generation in the case + * the conversion goes wrong. + */ + if (kether_aton(info->ethstr, enaddr) == NULL) { + 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[4] = (int)getpid() >> 8; - enaddr[5] = (int)getpid() & 255; - } - enaddr[1] += 1; + sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); diff --git a/sys/platform/vkernel64/include/md_var.h b/sys/platform/vkernel64/include/md_var.h index 286b2fb..7ff58d1 100644 --- a/sys/platform/vkernel64/include/md_var.h +++ b/sys/platform/vkernel64/include/md_var.h @@ -40,6 +40,11 @@ #ifndef _SYS_TYPES_H_ #include #endif + +#ifndef _NET_ETHERNET_H_ +#include +#endif + #ifndef _SYS_VKERNEL_H_ #include #endif @@ -52,6 +57,7 @@ struct vknetif_info { int tap_unit; in_addr_t netif_addr; in_addr_t netif_mask; + char ethstr[ETHER_ADDRSTRLEN]; }; struct vkdisk_info { diff --git a/sys/platform/vkernel64/platform/init.c b/sys/platform/vkernel64/platform/init.c index 2b0ca2d..9b5f810 100644 --- a/sys/platform/vkernel64/platform/init.c +++ b/sys/platform/vkernel64/platform/init.c @@ -1062,11 +1062,12 @@ unix_connect(const char *path) */ static int -netif_init_tap(int tap_unit, in_addr_t *addr, in_addr_t *mask, int s) +netif_init_tap(int tap_unit, in_addr_t *addr, in_addr_t *mask, char *macstr, int s) { in_addr_t tap_addr, netmask, netif_addr; int next_netif_addr; - char *tok, *masklen_str, *ifbridge; + char *tok, *masklen_str, *ifbridge, *mactmp; + int n; *addr = 0; *mask = 0; @@ -1127,7 +1128,7 @@ netif_init_tap(int tap_unit, in_addr_t *addr, in_addr_t *mask, int s) * Current token is pseudo netif address, if there is next token * it must be netmask len */ - masklen_str = strtok(NULL, "/"); + masklen_str = strtok(NULL, ":/"); } /* Calculate netmask */ @@ -1144,6 +1145,20 @@ netif_init_tap(int tap_unit, in_addr_t *addr, in_addr_t *mask, int s) } } + /* Check whether we were passed a MAC address */ + mactmp = strtok(NULL, ":/"); + if (mactmp != NULL) { + n = snprintf(macstr, 18, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c", + mactmp[0], mactmp[1], mactmp[2], mactmp[3], mactmp[4], + mactmp[5], mactmp[6], mactmp[7], mactmp[8], mactmp[9], + mactmp[10], mactmp[11]); + + if (n != 17) { + warnx("Invalid MAC address passed, %d args passed", n); + macstr = NULL; + } + } + /* Make sure there is no more token left */ if (strtok(NULL, ":/") != NULL) { warnx("Invalid argument to '-I'"); @@ -1178,6 +1193,7 @@ void init_netif(char *netifExp[], int netifExpNum) { int i, s; + char macstr[18]; if (netifExpNum == 0) return; @@ -1213,7 +1229,7 @@ init_netif(char *netifExp[], int netifExpNum) * NB: Rest part of netifExp[i] is passed * to netif_init_tap() implicitly. */ - if (netif_init_tap(tap_unit, &netif_addr, &netif_mask, s) < 0) { + if (netif_init_tap(tap_unit, &netif_addr, &netif_mask, macstr, s) < 0) { /* * NB: Closing tap(4) device file will bring * down the corresponding interface @@ -1223,11 +1239,18 @@ init_netif(char *netifExp[], int netifExpNum) } info = &NetifInfo[NetifNum]; + bzero(info, sizeof(*info)); info->tap_fd = tap_fd; 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 (macstr != NULL) + strlcpy(info->ethstr, macstr, 18); + NetifNum++; if (NetifNum >= VKNETIF_MAX) /* XXX will this happen? */ break;