net: adjust randomized address bits
Give devices that need a MAC a 16-bit allocation out of the FreeBSD Foundation OUI range. Change the name ether_fakeaddr to ether_gen_addr now that we're dealing real MAC addresses with a real OUI rather than random locally-administered addresses. Reviewed by: bz, rgrimes Differential Revision: https://reviews.freebsd.org/D19587
This commit is contained in:
parent
9817bae932
commit
3c3aa8c170
@ -422,7 +422,7 @@ void ether_vlan_mtap(struct bpf_if *, struct mbuf *,
|
||||
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_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr);
|
||||
|
||||
#ifdef _SYS_EVENTHANDLER_H_
|
||||
/* new ethernet interface attached event */
|
||||
|
@ -67,3 +67,14 @@
|
||||
/* 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 a pool to give to various interfaces that need a
|
||||
* generated address, but don't quite need to slice off a whole section of
|
||||
* the OUI (e.g. cloned interfaces, one-off NICs of various vendors).
|
||||
*
|
||||
* ether_gen_addr should be used to generate an address from this pool.
|
||||
*/
|
||||
#define OUI_FREEBSD_GENERATED_MASK 0x10ffff
|
||||
#define OUI_FREEBSD_GENERATED_LOW OUI_FREEBSD(0x100000)
|
||||
#define OUI_FREEBSD_GENERATED_HIGH OUI_FREEBSD(OU_FREEBSD_GENERATED_MASK)
|
||||
|
@ -671,7 +671,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
getcredhostid(curthread->td_ucred, &hostid);
|
||||
do {
|
||||
if (fb || hostid == 0) {
|
||||
ether_fakeaddr(&sc->sc_defaddr);
|
||||
ether_gen_addr(ifp, &sc->sc_defaddr);
|
||||
} else {
|
||||
sc->sc_defaddr.octet[0] = 0x2;
|
||||
sc->sc_defaddr.octet[1] = (hostid >> 24) & 0xff;
|
||||
|
@ -42,11 +42,13 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/socket.h>
|
||||
@ -54,6 +56,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/uuid.h>
|
||||
|
||||
#include <net/ieee_oui.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
@ -85,6 +88,8 @@
|
||||
#endif
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
#include <crypto/sha1.h>
|
||||
|
||||
#ifdef CTASSERT
|
||||
CTASSERT(sizeof (struct ether_header) == ETHER_ADDR_LEN * 2 + 2);
|
||||
CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN);
|
||||
@ -1401,19 +1406,37 @@ ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an address from the FreeBSD Foundation OUI. This uses a
|
||||
* cryptographic hash function on the containing jail's UUID and the interface
|
||||
* name to attempt to provide a unique but stable address. Pseudo-interfaces
|
||||
* which require a MAC address should use this function to allocate
|
||||
* non-locally-administered addresses.
|
||||
*/
|
||||
void
|
||||
ether_fakeaddr(struct ether_addr *hwaddr)
|
||||
ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr)
|
||||
{
|
||||
#define ETHER_GEN_ADDR_BUFSIZ HOSTUUIDLEN + IFNAMSIZ + 2
|
||||
SHA1_CTX ctx;
|
||||
char buf[ETHER_GEN_ADDR_BUFSIZ];
|
||||
char uuid[HOSTUUIDLEN + 1];
|
||||
uint64_t addr;
|
||||
int i, sz;
|
||||
char digest[SHA1_RESULTLEN];
|
||||
|
||||
/*
|
||||
* 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';
|
||||
getcredhostuuid(curthread->td_ucred, uuid, sizeof(uuid));
|
||||
sz = snprintf(buf, ETHER_GEN_ADDR_BUFSIZ, "%s-%s", uuid, ifp->if_xname);
|
||||
SHA1Init(&ctx);
|
||||
SHA1Update(&ctx, buf, sz);
|
||||
SHA1Final(digest, &ctx);
|
||||
|
||||
addr = ((digest[0] << 16) | (digest[1] << 8) | digest[2]) &
|
||||
OUI_FREEBSD_GENERATED_MASK;
|
||||
addr = OUI_FREEBSD(addr);
|
||||
for (i = 0; i < ETHER_ADDR_LEN; ++i) {
|
||||
hwaddr->octet[i] = addr >> ((ETHER_ADDR_LEN - i - 1) * 8) &
|
||||
0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_MODULE(ether, ether_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
|
||||
|
@ -2754,7 +2754,7 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
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_gen_addr(ifp, &sc->vxl_hwaddr);
|
||||
ether_ifattach(ifp, sc->vxl_hwaddr.octet);
|
||||
|
||||
ifp->if_baudrate = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user