svn commit: r346783 - in stable: 11/sys/conf 11/sys/net 12/sys/conf 12/sys/net
Kyle Evans
kevans at FreeBSD.org
Sat Apr 27 04:39:45 UTC 2019
Author: kevans
Date: Sat Apr 27 04:39:41 2019
New Revision: 346783
URL: https://svnweb.freebsd.org/changeset/base/346783
Log:
MFC r345139, r345151, r346324, r346328: ether_gen_addr KPI
if_bridge and if_vxlan conversion to this deterministic MAC address KPI has
been MFC as well. This is potentially error prone as the generated address
range for these has decreased, but I've deemed this acceptable for stable
branches due to collisions for thees interfaces being easily remedied.
I have no intention of switching anything else to this KPI in any stable
branches.
r345139:
ether: centralize fake hwaddr generation
We currently have two places with identical fake hwaddr generation --
if_vxlan and if_bridge. Lift it into if_ethersubr for reuse in other
interfaces that may also need a fake addr.
r345151:
ether_fakeaddr: Use 'b' 's' 'd' for the prefix
This has the advantage of being obvious to sniff out the designated prefix
by eye and it has all the right bits set. Comment stolen from ffec.
I've removed bryanv@'s pending question of using the FreeBSD OUI range --
no one has followed up on this with a definitive action, and there's no
particular reason to shoot for it and the administrative overhead that comes
with deciding exactly how to use it.
r346324:
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.
r346328:
Compile sha1.c when ether support is included
sha1 is used by ether_gen_addr after r346324. Perhaps in an ideal world we
could detect that the kernel's been compiled without sha1_* bits included
and silently fallback to arc4random instead because these platforms/kernel
configs are far and few between. It's fairly lightweight, though, so just
include it for now.
Modified:
stable/12/sys/conf/files
stable/12/sys/net/ethernet.h
stable/12/sys/net/ieee_oui.h
stable/12/sys/net/if_bridge.c
stable/12/sys/net/if_ethersubr.c
stable/12/sys/net/if_vxlan.c
Directory Properties:
stable/12/ (props changed)
Changes in other areas also in this revision:
Modified:
stable/11/sys/conf/files
stable/11/sys/net/ethernet.h
stable/11/sys/net/ieee_oui.h
stable/11/sys/net/if_bridge.c
stable/11/sys/net/if_ethersubr.c
stable/11/sys/net/if_vxlan.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/12/sys/conf/files
==============================================================================
--- stable/12/sys/conf/files Sat Apr 27 04:16:15 2019 (r346782)
+++ stable/12/sys/conf/files Sat Apr 27 04:39:41 2019 (r346783)
@@ -678,8 +678,8 @@ crypto/rijndael/rijndael-alg-fst.c optional crypto | e
crypto/rijndael/rijndael-api-fst.c optional ekcd | geom_bde | random !random_loadable
crypto/rijndael/rijndael-api.c optional crypto | ipsec | ipsec_support | \
wlan_ccmp
-crypto/sha1.c optional carp | crypto | ipsec | \
- ipsec_support | netgraph_mppc_encryption | sctp
+crypto/sha1.c optional carp | crypto | ether | ipsec | \
+ ipsec_support | netgraph_mppc_encryption | sctp
crypto/sha2/sha256c.c optional crypto | ekcd | geom_bde | ipsec | \
ipsec_support | random !random_loadable | sctp | zfs
crypto/sha2/sha512c.c optional crypto | geom_bde | ipsec | \
Modified: stable/12/sys/net/ethernet.h
==============================================================================
--- stable/12/sys/net/ethernet.h Sat Apr 27 04:16:15 2019 (r346782)
+++ stable/12/sys/net/ethernet.h Sat Apr 27 04:39:41 2019 (r346783)
@@ -422,6 +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_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr);
#ifdef _SYS_EVENTHANDLER_H_
/* new ethernet interface attached event */
Modified: stable/12/sys/net/ieee_oui.h
==============================================================================
--- stable/12/sys/net/ieee_oui.h Sat Apr 27 04:16:15 2019 (r346782)
+++ stable/12/sys/net/ieee_oui.h Sat Apr 27 04:39:41 2019 (r346783)
@@ -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: stable/12/sys/net/if_bridge.c
==============================================================================
--- stable/12/sys/net/if_bridge.c Sat Apr 27 04:16:15 2019 (r346782)
+++ stable/12/sys/net/if_bridge.c Sat Apr 27 04:39:41 2019 (r346783)
@@ -226,7 +226,7 @@ struct bridge_softc {
struct bstp_state sc_stp; /* STP state */
uint32_t sc_brtexceeded; /* # of cache drops */
struct ifnet *sc_ifaddr; /* member mac copied from */
- u_char sc_defaddr[6]; /* Default MAC address */
+ struct ether_addr sc_defaddr; /* Default MAC address */
};
VNET_DEFINE_STATIC(struct mtx, bridge_list_mtx);
@@ -671,16 +671,14 @@ bridge_clone_create(struct if_clone *ifc, int unit, ca
getcredhostid(curthread->td_ucred, &hostid);
do {
if (fb || hostid == 0) {
- arc4rand(sc->sc_defaddr, ETHER_ADDR_LEN, 1);
- sc->sc_defaddr[0] &= ~1;/* clear multicast bit */
- sc->sc_defaddr[0] |= 2; /* set the LAA bit */
+ ether_gen_addr(ifp, &sc->sc_defaddr);
} else {
- sc->sc_defaddr[0] = 0x2;
- sc->sc_defaddr[1] = (hostid >> 24) & 0xff;
- sc->sc_defaddr[2] = (hostid >> 16) & 0xff;
- sc->sc_defaddr[3] = (hostid >> 8 ) & 0xff;
- sc->sc_defaddr[4] = hostid & 0xff;
- sc->sc_defaddr[5] = ifp->if_dunit & 0xff;
+ sc->sc_defaddr.octet[0] = 0x2;
+ sc->sc_defaddr.octet[1] = (hostid >> 24) & 0xff;
+ sc->sc_defaddr.octet[2] = (hostid >> 16) & 0xff;
+ sc->sc_defaddr.octet[3] = (hostid >> 8 ) & 0xff;
+ sc->sc_defaddr.octet[4] = hostid & 0xff;
+ sc->sc_defaddr.octet[5] = ifp->if_dunit & 0xff;
}
fb = 1;
@@ -688,7 +686,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, ca
BRIDGE_LIST_LOCK();
LIST_FOREACH(sc2, &V_bridge_list, sc_list) {
bifp = sc2->sc_ifp;
- if (memcmp(sc->sc_defaddr,
+ if (memcmp(sc->sc_defaddr.octet,
IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) {
retry = 1;
break;
@@ -698,7 +696,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, ca
} while (retry == 1);
bstp_attach(&sc->sc_stp, &bridge_ops);
- ether_ifattach(ifp, sc->sc_defaddr);
+ ether_ifattach(ifp, sc->sc_defaddr.octet);
/* Now undo some of the damage... */
ifp->if_baudrate = 0;
ifp->if_type = IFT_BRIDGE;
@@ -1019,7 +1017,7 @@ bridge_delete_member(struct bridge_softc *sc, struct b
*/
if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) {
if (LIST_EMPTY(&sc->sc_iflist)) {
- bcopy(sc->sc_defaddr,
+ bcopy(&sc->sc_defaddr,
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
sc->sc_ifaddr = NULL;
} else {
@@ -1190,7 +1188,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
* the default randomly generated one.
*/
if (V_bridge_inherit_mac && LIST_EMPTY(&sc->sc_iflist) &&
- !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr, ETHER_ADDR_LEN)) {
+ !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr.octet, ETHER_ADDR_LEN)) {
bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
sc->sc_ifaddr = ifs;
EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp);
Modified: stable/12/sys/net/if_ethersubr.c
==============================================================================
--- stable/12/sys/net/if_ethersubr.c Sat Apr 27 04:16:15 2019 (r346782)
+++ stable/12/sys/net/if_ethersubr.c Sat Apr 27 04:39:41 2019 (r346783)
@@ -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);
@@ -1366,6 +1371,39 @@ 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_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];
+
+ 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: stable/12/sys/net/if_vxlan.c
==============================================================================
--- stable/12/sys/net/if_vxlan.c Sat Apr 27 04:16:15 2019 (r346782)
+++ stable/12/sys/net/if_vxlan.c Sat Apr 27 04:39:41 2019 (r346783)
@@ -177,7 +177,7 @@ struct vxlan_softc {
struct sysctl_oid *vxl_sysctl_node;
struct sysctl_ctx_list vxl_sysctl_ctx;
struct callout vxl_callout;
- uint8_t vxl_hwaddr[ETHER_ADDR_LEN];
+ struct ether_addr vxl_hwaddr;
int vxl_mc_ifindex;
struct ifnet *vxl_mc_ifp;
struct ifmedia vxl_media;
@@ -345,7 +345,6 @@ static int vxlan_clone_create(struct if_clone *, int,
static void vxlan_clone_destroy(struct ifnet *);
static uint32_t vxlan_mac_hash(struct vxlan_softc *, const uint8_t *);
-static void vxlan_fakeaddr(struct vxlan_softc *);
static int vxlan_media_change(struct ifnet *);
static void vxlan_media_status(struct ifnet *, struct ifmediareq *);
@@ -2755,8 +2754,8 @@ 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);
- vxlan_fakeaddr(sc);
- ether_ifattach(ifp, sc->vxl_hwaddr);
+ ether_gen_addr(ifp, &sc->vxl_hwaddr);
+ ether_ifattach(ifp, sc->vxl_hwaddr.octet);
ifp->if_baudrate = 0;
ifp->if_hdrlen = 0;
@@ -2825,20 +2824,6 @@ do { \
#undef mix
return (c);
-}
-
-static void
-vxlan_fakeaddr(struct vxlan_softc *sc)
-{
-
- /*
- * Generate a non-multicast, locally administered address.
- *
- * BMV: Should we use the FreeBSD OUI range instead?
- */
- arc4rand(sc->vxl_hwaddr, ETHER_ADDR_LEN, 1);
- sc->vxl_hwaddr[0] &= ~1;
- sc->vxl_hwaddr[0] |= 2;
}
static int
More information about the svn-src-stable
mailing list