Index: sys/net/ethernet.h =================================================================== --- sys/net/ethernet.h +++ sys/net/ethernet.h @@ -422,7 +422,8 @@ struct mbuf *ether_vlanencap(struct mbuf *, uint16_t); bool ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p, uint16_t vid, uint8_t pcp); -void ether_fakeaddr(struct ether_addr *hwaddr); +void ether_randomaddr_lowmask(struct ether_addr *hwaddr, uint32_t mask); +void ether_randomaddr(struct ether_addr *hwaddr); #ifdef _SYS_EVENTHANDLER_H_ /* new ethernet interface attached event */ Index: sys/net/ieee_oui.h =================================================================== --- sys/net/ieee_oui.h +++ sys/net/ieee_oui.h @@ -67,3 +67,8 @@ /* Allocate 20 bits to bhyve */ #define OUI_FREEBSD_BHYVE_LOW OUI_FREEBSD(0x000001) #define OUI_FREEBSD_BHYVE_HIGH OUI_FREEBSD(0x0fffff) + +/* Allocate 16 bits for random pool */ +#define OUI_FREEBSD_RANDOM_MASK 0x10ffff +#define OUI_FREEBSD_RANDOM_LOW OUI_FREEBSD(0x100000) +#define OUI_FREEBSD_RANDOM_HIGH OUI_FREEBSD(OU_FREEBSD_RANDOM_MASK) Index: sys/net/if_bridge.c =================================================================== --- sys/net/if_bridge.c +++ sys/net/if_bridge.c @@ -670,7 +670,7 @@ getcredhostid(curthread->td_ucred, &hostid); do { if (fb || hostid == 0) { - ether_fakeaddr(&sc->sc_defaddr); + ether_randomaddr(&sc->sc_defaddr); } else { sc->sc_defaddr.octet[0] = 0x2; sc->sc_defaddr.octet[1] = (hostid >> 24) & 0xff; Index: sys/net/if_ethersubr.c =================================================================== --- sys/net/if_ethersubr.c +++ sys/net/if_ethersubr.c @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -1401,19 +1402,31 @@ return (true); } +/* + * Allocate a random address from the FreeBSD Foundation OUI. The mask should + * indicate the specific sub-allocation that the address should come out of. + * This is intended to centralize the various 'random' allocations using + * non-locally-administered addresses to avoid trampling on potentially + * conflicting environments that consumers of this will be deployed in. + */ void -ether_fakeaddr(struct ether_addr *hwaddr) +ether_randomaddr_lowmask(struct ether_addr *hwaddr, uint32_t mask) { + uint64_t addr; + int i; - /* - * Generate a convenient locally administered address, - * 'bsd' + random 24 low-order bits. 'b' is 0x62, which has the locally - * assigned bit set, and the broadcast/multicast bit clear. - */ - arc4rand(hwaddr->octet, ETHER_ADDR_LEN, 1); - hwaddr->octet[0] = 'b'; - hwaddr->octet[1] = 's'; - hwaddr->octet[2] = 'd'; + addr = OUI_FREEBSD(arc4random() & mask); + for (i = 0; i < ETHER_ADDR_LEN; ++i) { + hwaddr->octet[i] = addr >> ((ETHER_ADDR_LEN - i - 1) * 8) & + 0xFF; + } +} + +void +ether_randomaddr(struct ether_addr *hwaddr) +{ + + ether_randomaddr_lowmask(hwaddr, OUI_FREEBSD_RANDOM_MASK); } DECLARE_MODULE(ether, ether_mod, SI_SUB_INIT_IF, SI_ORDER_ANY); Index: sys/net/if_vxlan.c =================================================================== --- sys/net/if_vxlan.c +++ sys/net/if_vxlan.c @@ -2754,7 +2754,7 @@ ifmedia_add(&sc->vxl_media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->vxl_media, IFM_ETHER | IFM_AUTO); - ether_fakeaddr(&sc->vxl_hwaddr); + ether_randomaddr(&sc->vxl_hwaddr); ether_ifattach(ifp, sc->vxl_hwaddr.octet); ifp->if_baudrate = 0; Index: sys/net/iflib.c =================================================================== --- sys/net/iflib.c +++ sys/net/iflib.c @@ -1301,9 +1301,10 @@ mac[0] = 0x58; mac[1] = 0x9C; mac[2] = 0xFC; - mac[3] = digest[0]; - mac[4] = digest[1]; - mac[5] = digest[2]; + /* Mask it into the 'random' OUI pool */ + mac[3] = digest[0] & 0x10; + mac[4] = digest[1] & 0xff; + mac[5] = digest[2] & 0xff; } static void