Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/if_bridge.c
Show First 20 Lines • Show All 220 Lines • ▼ Show 20 Lines | struct bridge_softc { | ||||
LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */ | LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */ | ||||
LIST_HEAD(, bridge_rtnode) *sc_rthash; /* our forwarding table */ | LIST_HEAD(, bridge_rtnode) *sc_rthash; /* our forwarding table */ | ||||
LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */ | LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */ | ||||
uint32_t sc_rthash_key; /* key for hash */ | uint32_t sc_rthash_key; /* key for hash */ | ||||
LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */ | LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */ | ||||
struct bstp_state sc_stp; /* STP state */ | struct bstp_state sc_stp; /* STP state */ | ||||
uint32_t sc_brtexceeded; /* # of cache drops */ | uint32_t sc_brtexceeded; /* # of cache drops */ | ||||
struct ifnet *sc_ifaddr; /* member mac copied from */ | 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); | VNET_DEFINE_STATIC(struct mtx, bridge_list_mtx); | ||||
#define V_bridge_list_mtx VNET(bridge_list_mtx) | #define V_bridge_list_mtx VNET(bridge_list_mtx) | ||||
static eventhandler_tag bridge_detach_cookie; | static eventhandler_tag bridge_detach_cookie; | ||||
int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; | int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; | ||||
▲ Show 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params) | ||||
* possible that we might have address collisions, so make sure that | * possible that we might have address collisions, so make sure that | ||||
* this hardware address isn't already in use on another bridge. | * this hardware address isn't already in use on another bridge. | ||||
* The first try uses the hostid and falls back to arc4rand(). | * The first try uses the hostid and falls back to arc4rand(). | ||||
*/ | */ | ||||
fb = 0; | fb = 0; | ||||
getcredhostid(curthread->td_ucred, &hostid); | getcredhostid(curthread->td_ucred, &hostid); | ||||
do { | do { | ||||
if (fb || hostid == 0) { | if (fb || hostid == 0) { | ||||
arc4rand(sc->sc_defaddr, ETHER_ADDR_LEN, 1); | ether_fakeaddr(&sc->sc_defaddr); | ||||
sc->sc_defaddr[0] &= ~1;/* clear multicast bit */ | |||||
sc->sc_defaddr[0] |= 2; /* set the LAA bit */ | |||||
} else { | } else { | ||||
sc->sc_defaddr[0] = 0x2; | sc->sc_defaddr.octet[0] = 0x2; | ||||
sc->sc_defaddr[1] = (hostid >> 24) & 0xff; | sc->sc_defaddr.octet[1] = (hostid >> 24) & 0xff; | ||||
sc->sc_defaddr[2] = (hostid >> 16) & 0xff; | sc->sc_defaddr.octet[2] = (hostid >> 16) & 0xff; | ||||
sc->sc_defaddr[3] = (hostid >> 8 ) & 0xff; | sc->sc_defaddr.octet[3] = (hostid >> 8 ) & 0xff; | ||||
sc->sc_defaddr[4] = hostid & 0xff; | sc->sc_defaddr.octet[4] = hostid & 0xff; | ||||
sc->sc_defaddr[5] = ifp->if_dunit & 0xff; | sc->sc_defaddr.octet[5] = ifp->if_dunit & 0xff; | ||||
} | } | ||||
fb = 1; | fb = 1; | ||||
retry = 0; | retry = 0; | ||||
BRIDGE_LIST_LOCK(); | BRIDGE_LIST_LOCK(); | ||||
LIST_FOREACH(sc2, &V_bridge_list, sc_list) { | LIST_FOREACH(sc2, &V_bridge_list, sc_list) { | ||||
bifp = sc2->sc_ifp; | bifp = sc2->sc_ifp; | ||||
if (memcmp(sc->sc_defaddr, | if (memcmp(sc->sc_defaddr.octet, | ||||
IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) { | IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) { | ||||
retry = 1; | retry = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
BRIDGE_LIST_UNLOCK(); | BRIDGE_LIST_UNLOCK(); | ||||
} while (retry == 1); | } while (retry == 1); | ||||
bstp_attach(&sc->sc_stp, &bridge_ops); | 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... */ | /* Now undo some of the damage... */ | ||||
ifp->if_baudrate = 0; | ifp->if_baudrate = 0; | ||||
ifp->if_type = IFT_BRIDGE; | ifp->if_type = IFT_BRIDGE; | ||||
BRIDGE_LIST_LOCK(); | BRIDGE_LIST_LOCK(); | ||||
LIST_INSERT_HEAD(&V_bridge_list, sc, sc_list); | LIST_INSERT_HEAD(&V_bridge_list, sc, sc_list); | ||||
BRIDGE_LIST_UNLOCK(); | BRIDGE_LIST_UNLOCK(); | ||||
▲ Show 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif, | ||||
/* | /* | ||||
* If removing the interface that gave the bridge its mac address, set | * If removing the interface that gave the bridge its mac address, set | ||||
* the mac address of the bridge to the address of the next member, or | * the mac address of the bridge to the address of the next member, or | ||||
* to its default address if no members are left. | * to its default address if no members are left. | ||||
*/ | */ | ||||
if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) { | if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) { | ||||
if (LIST_EMPTY(&sc->sc_iflist)) { | if (LIST_EMPTY(&sc->sc_iflist)) { | ||||
bcopy(sc->sc_defaddr, | bcopy(&sc->sc_defaddr, | ||||
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); | IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); | ||||
sc->sc_ifaddr = NULL; | sc->sc_ifaddr = NULL; | ||||
} else { | } else { | ||||
fif = LIST_FIRST(&sc->sc_iflist)->bif_ifp; | fif = LIST_FIRST(&sc->sc_iflist)->bif_ifp; | ||||
bcopy(IF_LLADDR(fif), | bcopy(IF_LLADDR(fif), | ||||
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); | IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); | ||||
sc->sc_ifaddr = fif; | sc->sc_ifaddr = fif; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | #endif | ||||
bif->bif_savedcaps = ifs->if_capenable; | bif->bif_savedcaps = ifs->if_capenable; | ||||
/* | /* | ||||
* Assign the interface's MAC address to the bridge if it's the first | * Assign the interface's MAC address to the bridge if it's the first | ||||
* member and the MAC address of the bridge has not been changed from | * member and the MAC address of the bridge has not been changed from | ||||
* the default randomly generated one. | * the default randomly generated one. | ||||
*/ | */ | ||||
if (V_bridge_inherit_mac && LIST_EMPTY(&sc->sc_iflist) && | 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); | bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); | ||||
sc->sc_ifaddr = ifs; | sc->sc_ifaddr = ifs; | ||||
EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); | EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); | ||||
} | } | ||||
ifs->if_bridge = sc; | ifs->if_bridge = sc; | ||||
ifs->if_bridge_output = bridge_output; | ifs->if_bridge_output = bridge_output; | ||||
ifs->if_bridge_input = bridge_input; | ifs->if_bridge_input = bridge_input; | ||||
▲ Show 20 Lines • Show All 2,406 Lines • Show Last 20 Lines |