summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2011-09-04 22:06:32 +0000
committerthompsa <thompsa@FreeBSD.org>2011-09-04 22:06:32 +0000
commitcb24e9343dfdd2c90611cefacb0016af3e769349 (patch)
tree9236de74ebea7e8cd3aa9f38120691d6e78d6bc4 /sys/net
parentef6fc882acfd1cfb8bbb5c729679924a4be0d4b5 (diff)
downloadFreeBSD-src-cb24e9343dfdd2c90611cefacb0016af3e769349.zip
FreeBSD-src-cb24e9343dfdd2c90611cefacb0016af3e769349.tar.gz
On the first loop for generating a bridge MAC address use the local
hostid, this gives a good chance of keeping the same address over reboots. This is intended to help IPV6 and similar which generate their addresses from the mac. PR: kern/160300 Submitted by: mdodd Approved by: re (kib)
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_bridge.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index a4bf2b2..c251653 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/protosw.h>
#include <sys/systm.h>
+#include <sys/jail.h>
#include <sys/time.h>
#include <sys/socket.h> /* for net/if.h */
#include <sys/sockio.h>
@@ -560,7 +561,8 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct bridge_softc *sc, *sc2;
struct ifnet *bifp, *ifp;
- int retry;
+ int fb, retry;
+ unsigned long hostid;
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
@@ -593,17 +595,30 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
IFQ_SET_READY(&ifp->if_snd);
/*
- * Generate a random ethernet address with a locally administered
- * address.
+ * Generate an ethernet address with a locally administered address.
*
* Since we are using random ethernet addresses for the bridge, it is
* possible that we might have address collisions, so make sure that
* this hardware address isn't already in use on another bridge.
+ * The first try uses the hostid and falls back to arc4rand().
*/
+ fb = 0;
+ getcredhostid(curthread->td_ucred, &hostid);
for (retry = 1; retry != 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 */
+ 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 */
+ } 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;
+ }
+
+ fb = 1;
retry = 0;
mtx_lock(&bridge_list_mtx);
LIST_FOREACH(sc2, &bridge_list, sc_list) {
OpenPOWER on IntegriCloud