summaryrefslogtreecommitdiff
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c190
1 files changed, 64 insertions, 126 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 54503a16dc6..72e244b9f48 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.196 2012/09/20 14:10:18 mpf Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.197 2012/10/05 17:17:04 camield Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -273,7 +273,7 @@ bridge_delete(struct bridge_softc *sc, struct bridge_iflist *p)
if (p->bif_flags & IFBIF_STP)
bstp_delete(p->bif_stp);
- p->ifp->if_bridge = NULL;
+ p->ifp->if_bridgeport = NULL;
error = ifpromisc(p->ifp, 0);
LIST_REMOVE(p, next);
@@ -310,11 +310,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
- if (ifs->if_bridge == (caddr_t)sc) {
- error = EEXIST;
- break;
- }
- if (ifs->if_bridge != NULL) {
+ if (ifs->if_bridgeport != NULL) {
error = EBUSY;
break;
}
@@ -384,28 +380,28 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
+ p->bridge_sc = sc;
p->ifp = ifs;
p->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
SIMPLEQ_INIT(&p->bif_brlin);
SIMPLEQ_INIT(&p->bif_brlout);
- ifs->if_bridge = (caddr_t)sc;
+ ifs->if_bridgeport = (caddr_t)p;
LIST_INSERT_HEAD(&sc->sc_iflist, p, next);
break;
case SIOCBRDGDEL:
if ((error = suser(curproc, 0)) != 0)
break;
-
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if (strncmp(p->ifp->if_xname, req->ifbr_ifsname,
- sizeof(p->ifp->if_xname)) == 0) {
- error = bridge_delete(sc, p);
- break;
- }
- }
- if (p == LIST_END(&sc->sc_iflist)) {
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) {
error = ENOENT;
break;
}
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
+ error = ESRCH;
+ break;
+ }
+ error = bridge_delete(sc, p);
break;
case SIOCBRDGIFS:
error = bridge_bifconf(sc, (struct ifbifconf *)data);
@@ -418,11 +414,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
- if (ifs->if_bridge == (caddr_t)sc) {
- error = EEXIST;
- break;
- }
- if (ifs->if_bridge != NULL) {
+ if (ifs->if_bridgeport != NULL) {
error = EBUSY;
break;
}
@@ -467,15 +459,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
- if ((caddr_t)sc != ifs->if_bridge) {
- error = ESRCH;
- break;
- }
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if (p->ifp == ifs)
- break;
- }
- if (p == LIST_END(&sc->sc_iflist)) {
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
error = ESRCH;
break;
}
@@ -515,15 +500,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
- if ((caddr_t)sc != ifs->if_bridge) {
- error = ESRCH;
- break;
- }
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if (p->ifp == ifs)
- break;
- }
- if (p == LIST_END(&sc->sc_iflist)) {
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
error = ESRCH;
break;
}
@@ -561,15 +539,13 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCBRDGSADDR:
if ((error = suser(curproc, 0)) != 0)
break;
-
ifs = ifunit(bareq->ifba_ifsname);
if (ifs == NULL) { /* no such interface */
error = ENOENT;
break;
}
-
- if (ifs->if_bridge == NULL ||
- ifs->if_bridge != (caddr_t)sc) {
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
error = ESRCH;
break;
}
@@ -626,16 +602,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
- if (ifs->if_bridge == NULL ||
- ifs->if_bridge != (caddr_t)sc) {
- error = ESRCH;
- break;
- }
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if (p->ifp == ifs)
- break;
- }
- if (p == LIST_END(&sc->sc_iflist)) {
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
error = ESRCH;
break;
}
@@ -664,16 +632,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
- if (ifs->if_bridge == NULL ||
- ifs->if_bridge != (caddr_t)sc) {
- error = ESRCH;
- break;
- }
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if (p->ifp == ifs)
- break;
- }
- if (p == LIST_END(&sc->sc_iflist)) {
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
error = ESRCH;
break;
}
@@ -731,51 +691,49 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
void
bridge_ifdetach(struct ifnet *ifp)
{
- struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
+ struct bridge_softc *sc;
struct bridge_iflist *bif;
- LIST_FOREACH(bif, &sc->sc_iflist, next)
- if (bif->ifp == ifp) {
- bridge_delete(sc, bif);
- break;
- }
+ bif = (struct bridge_iflist *)ifp->if_bridgeport;
+ sc = bif->bridge_sc;
+
+ bridge_delete(sc, bif);
}
void
bridge_update(struct ifnet *ifp, struct ether_addr *ea, int delete)
{
- struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
+ struct bridge_softc *sc;
struct bridge_iflist *bif;
u_int8_t *addr;
addr = (u_int8_t *)ea;
- LIST_FOREACH(bif, &sc->sc_iflist, next)
- if (bif->ifp == ifp) {
- /*
- * Update the bridge interface if it is in
- * the learning state.
- */
- if ((bif->bif_flags & IFBIF_LEARNING) &&
- (ETHER_IS_MULTICAST(addr) == 0) &&
- !(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 &&
- addr[3] == 0 && addr[4] == 0 && addr[5] == 0)) {
- /* Care must be taken with spanning tree */
- if ((bif->bif_flags & IFBIF_STP) &&
- (bif->bif_state == BSTP_IFSTATE_DISCARDING))
- return;
+ bif = (struct bridge_iflist *)ifp->if_bridgeport;
+ sc = bif->bridge_sc;
- /* Delete the address from the bridge */
- bridge_rtdaddr(sc, ea);
-
- if (!delete) {
- /* Update the bridge table */
- bridge_rtupdate(sc, ea, ifp, 0,
- IFBAF_DYNAMIC);
- }
- }
+ /*
+ * Update the bridge interface if it is in
+ * the learning state.
+ */
+ if ((bif->bif_flags & IFBIF_LEARNING) &&
+ (ETHER_IS_MULTICAST(addr) == 0) &&
+ !(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 &&
+ addr[3] == 0 && addr[4] == 0 && addr[5] == 0)) {
+ /* Care must be taken with spanning tree */
+ if ((bif->bif_flags & IFBIF_STP) &&
+ (bif->bif_state == BSTP_IFSTATE_DISCARDING))
return;
+
+ /* Delete the address from the bridge */
+ bridge_rtdaddr(sc, ea);
+
+ if (!delete) {
+ /* Update the bridge table */
+ bridge_rtupdate(sc, ea, ifp, 0, IFBAF_DYNAMIC);
}
+ }
+ return;
}
int
@@ -879,13 +837,8 @@ bridge_brlconf(struct bridge_softc *sc, struct ifbrlconf *bc)
ifp = ifunit(bc->ifbrl_ifsname);
if (ifp == NULL)
return (ENOENT);
- if (ifp->if_bridge == NULL || ifp->if_bridge != (caddr_t)sc)
- return (ESRCH);
- LIST_FOREACH(ifl, &sc->sc_iflist, next) {
- if (ifl->ifp == ifp)
- break;
- }
- if (ifl == LIST_END(&sc->sc_iflist))
+ ifl = (struct bridge_iflist *)ifp->if_bridgeport;
+ if (ifl == NULL || ifl->bridge_sc != sc)
return (ESRCH);
SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) {
@@ -1005,11 +958,11 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
#endif /* IPSEC */
/* ifp must be a member interface of the bridge. */
- sc = (struct bridge_softc *)ifp->if_bridge;
- if (sc == NULL) {
+ if (ifp->if_bridgeport == NULL) {
m_freem(m);
return (EINVAL);
}
+ sc = ((struct bridge_iflist *)ifp->if_bridgeport)->bridge_sc;
if (m->m_len < sizeof(*eh)) {
m = m_pullup(m, sizeof(*eh));
@@ -1207,11 +1160,8 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
sc->sc_if.if_ipackets++;
sc->sc_if.if_ibytes += m->m_pkthdr.len;
- LIST_FOREACH(ifl, &sc->sc_iflist, next)
- if (ifl->ifp == src_if)
- break;
-
- if (ifl == LIST_END(&sc->sc_iflist)) {
+ ifl = (struct bridge_iflist *)src_if->if_bridgeport;
+ if (ifl == NULL) {
m_freem(m);
return;
}
@@ -1327,14 +1277,7 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
m_freem(m);
return;
}
- LIST_FOREACH(ifl, &sc->sc_iflist, next) {
- if (ifl->ifp == dst_if)
- break;
- }
- if (ifl == LIST_END(&sc->sc_iflist)) {
- m_freem(m);
- return;
- }
+ ifl = (struct bridge_iflist *)dst_if->if_bridgeport;
if ((ifl->bif_flags & IFBIF_STP) &&
(ifl->bif_state == BSTP_IFSTATE_DISCARDING)) {
m_freem(m);
@@ -1379,7 +1322,7 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
/*
* Make sure this interface is a bridge member.
*/
- if (ifp == NULL || ifp->if_bridge == NULL || m == NULL)
+ if (ifp == NULL || ifp->if_bridgeport == NULL || m == NULL)
return (m);
if ((m->m_flags & M_PKTHDR) == 0)
@@ -1387,17 +1330,11 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
m->m_flags &= ~M_PROTO1; /* Loop prevention */
- sc = (struct bridge_softc *)ifp->if_bridge;
+ ifl = (struct bridge_iflist *)ifp->if_bridgeport;
+ sc = ifl->bridge_sc;
if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
return (m);
- LIST_FOREACH(ifl, &sc->sc_iflist, next) {
- if (ifl->ifp == ifp)
- break;
- }
- if (ifl == LIST_END(&sc->sc_iflist))
- return (m);
-
#if NBPFILTER > 0
if (sc->sc_if.if_bpf)
bpf_mtap_hdr(sc->sc_if.if_bpf, (caddr_t)eh,
@@ -2000,10 +1937,11 @@ bridge_rtage(struct bridge_softc *sc)
void
bridge_rtagenode(struct ifnet *ifp, int age)
{
- struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
+ struct bridge_softc *sc;
struct bridge_rtnode *n;
int i;
+ sc = ((struct bridge_iflist *)ifp->if_bridgeport)->bridge_sc;
if (sc == NULL)
return;