diff options
author | Andrew Thompson <thompsa@FreeBSD.org> | 2006-03-03 09:12:21 +0000 |
---|---|---|
committer | Andrew Thompson <thompsa@FreeBSD.org> | 2006-03-03 09:12:21 +0000 |
commit | 158a726c96999e08e01871a4b01853aa796d9f58 (patch) | |
tree | 4882680892f532eccd4e448aaab419f214a452dc /sys/net/if_bridge.c | |
parent | 6815739e006f4238621c6606962cc034628b974f (diff) | |
download | src-158a726c96999e08e01871a4b01853aa796d9f58.tar.gz src-158a726c96999e08e01871a4b01853aa796d9f58.zip |
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.
Submitted by: csjp
MFC after: 1 month
Notes
Notes:
svn path=/head/; revision=156238
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r-- | sys/net/if_bridge.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index d230238e95ae..caf24af2464a 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -450,9 +450,10 @@ SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW, static int bridge_clone_create(struct if_clone *ifc, int unit) { - struct bridge_softc *sc; - struct ifnet *ifp; + struct bridge_softc *sc, *sc2; + struct ifnet *bifp, *ifp; u_char eaddr[6]; + int retry; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); BRIDGE_LOCK_INIT(sc); @@ -496,11 +497,25 @@ bridge_clone_create(struct if_clone *ifc, int unit) /* * Generate a random ethernet address and use the private AC:DE:48 * OUI code. + * + * 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. */ - arc4rand(eaddr, ETHER_ADDR_LEN, 1); - eaddr[0] = 0xAC; - eaddr[1] = 0xDE; - eaddr[2] = 0x48; + for (retry = 1; retry != 0;) { + arc4rand(eaddr, ETHER_ADDR_LEN, 1); + eaddr[0] = 0xAC; + eaddr[1] = 0xDE; + eaddr[2] = 0x48; + retry = 0; + mtx_lock(&bridge_list_mtx); + LIST_FOREACH(sc2, &bridge_list, sc_list) { + bifp = sc2->sc_ifp; + if (memcmp(eaddr, IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) + retry = 1; + } + mtx_unlock(&bridge_list_mtx); + } ether_ifattach(ifp, eaddr); /* Now undo some of the damage... */ |