svn commit: r346324 - head/sys/net
Kyle Evans
kevans at FreeBSD.org
Wed Apr 17 17:18:45 UTC 2019
Author: kevans
Date: Wed Apr 17 17:18:43 2019
New Revision: 346324
URL: https://svnweb.freebsd.org/changeset/base/346324
Log:
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
Modified:
head/sys/net/ethernet.h
head/sys/net/ieee_oui.h
head/sys/net/if_bridge.c
head/sys/net/if_ethersubr.c
head/sys/net/if_vxlan.c
Modified: head/sys/net/ethernet.h
==============================================================================
--- head/sys/net/ethernet.h Wed Apr 17 17:00:16 2019 (r346323)
+++ head/sys/net/ethernet.h Wed Apr 17 17:18:43 2019 (r346324)
@@ -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 */
Modified: head/sys/net/ieee_oui.h
==============================================================================
--- head/sys/net/ieee_oui.h Wed Apr 17 17:00:16 2019 (r346323)
+++ head/sys/net/ieee_oui.h Wed Apr 17 17:18:43 2019 (r346324)
@@ -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)
Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c Wed Apr 17 17:00:16 2019 (r346323)
+++ head/sys/net/if_bridge.c Wed Apr 17 17:18:43 2019 (r346324)
@@ -671,7 +671,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, ca
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;
Modified: head/sys/net/if_ethersubr.c
==============================================================================
--- head/sys/net/if_ethersubr.c Wed Apr 17 17:00:16 2019 (r346323)
+++ head/sys/net/if_ethersubr.c Wed Apr 17 17:18:43 2019 (r346324)
@@ -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,
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);
Modified: head/sys/net/if_vxlan.c
==============================================================================
--- head/sys/net/if_vxlan.c Wed Apr 17 17:00:16 2019 (r346323)
+++ head/sys/net/if_vxlan.c Wed Apr 17 17:18:43 2019 (r346324)
@@ -2754,7 +2754,7 @@ vxlan_clone_create(struct if_clone *ifc, int unit, cad
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;
More information about the svn-src-all
mailing list