summaryrefslogtreecommitdiffstats
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2006-03-03 09:12:21 +0000
committerthompsa <thompsa@FreeBSD.org>2006-03-03 09:12:21 +0000
commit9bd7f368e04e01000d071ccc3e04aa86ff0e7a9f (patch)
tree4882680892f532eccd4e448aaab419f214a452dc /sys/net/if_bridge.c
parent8c627962e739865d2bdf5d7a40cc79885e69c7e0 (diff)
downloadFreeBSD-src-9bd7f368e04e01000d071ccc3e04aa86ff0e7a9f.zip
FreeBSD-src-9bd7f368e04e01000d071ccc3e04aa86ff0e7a9f.tar.gz
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
Diffstat (limited to 'sys/net/if_bridge.c')
-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 d230238..caf24af 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... */
OpenPOWER on IntegriCloud