summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorCamiel Dobbelaar <camield@cvs.openbsd.org>2012-10-05 17:17:05 +0000
committerCamiel Dobbelaar <camield@cvs.openbsd.org>2012-10-05 17:17:05 +0000
commit97f361f45ba615c51d5ed3d199661695056d69fd (patch)
treed587043476b3011e4b9d407ae8f76b924f697564 /sys/net
parentf9456dc1995e86224b952c3e98063ed528245036 (diff)
Point an interface directly to its bridgeport configuration, instead
of to the bridge itself. This is ok, since an interface can only be part of one bridge, and the parent bridge is easy to find from the bridgeport. This way we can get rid of a lot of list walks, improving performance and shortening the code. ok henning stsp sthen reyk
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/bridgestp.c27
-rw-r--r--sys/net/if.c8
-rw-r--r--sys/net/if.h4
-rw-r--r--sys/net/if_bridge.c190
-rw-r--r--sys/net/if_bridge.h7
-rw-r--r--sys/net/if_ethersubr.c15
-rw-r--r--sys/net/if_gif.c4
7 files changed, 92 insertions, 163 deletions
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c
index 70c4e63511a..5ae8ca1d635 100644
--- a/sys/net/bridgestp.c
+++ b/sys/net/bridgestp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bridgestp.c,v 1.41 2012/09/20 14:10:18 mpf Exp $ */
+/* $OpenBSD: bridgestp.c,v 1.42 2012/10/05 17:17:04 camield Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
@@ -1641,7 +1641,6 @@ void
bstp_ifstate(void *arg)
{
struct ifnet *ifp = (struct ifnet *)arg;
- struct bridge_softc *sc;
struct bridge_iflist *p;
struct bstp_port *bp;
struct bstp_state *bs;
@@ -1649,16 +1648,11 @@ bstp_ifstate(void *arg)
if (ifp->if_type == IFT_BRIDGE)
return;
- sc = (struct bridge_softc *)ifp->if_bridge;
s = splnet();
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if ((p->bif_flags & IFBIF_STP) == 0)
- continue;
- if (p->ifp == ifp)
- break;
- }
- if (p == LIST_END(&sc->sc_iflist))
+ if ((p = (struct bridge_iflist *)ifp->if_bridgeport) == NULL)
+ goto done;
+ if ((p->bif_flags & IFBIF_STP) == 0)
goto done;
if ((bp = p->bif_stp) == NULL)
goto done;
@@ -2121,7 +2115,7 @@ bstp_ifsflags(struct bstp_port *bp, u_int flags)
int
bstp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct bridge_softc *sc = (struct bridge_softc *)ifp;
+ struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc;
struct bstp_state *bs = sc->sc_stp;
struct ifbrparam *ifbp = (struct ifbrparam *)data;
struct ifbreq *ifbr = (struct ifbreq *)data;
@@ -2138,15 +2132,8 @@ bstp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
err = ENOENT;
break;
}
- if ((caddr_t)sc != ifs->if_bridge) {
- err = 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) {
err = ESRCH;
break;
}
diff --git a/sys/net/if.c b/sys/net/if.c
index c2132ab5c8b..086c2d36769 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.244 2012/09/19 16:14:01 blambert Exp $ */
+/* $OpenBSD: if.c,v 1.245 2012/10/05 17:17:04 camield Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -531,7 +531,7 @@ if_detach(struct ifnet *ifp)
#if NBRIDGE > 0
/* Remove the interface from any bridge it is part of. */
- if (ifp->if_bridge)
+ if (ifp->if_bridgeport)
bridge_ifdetach(ifp);
#endif
@@ -1094,7 +1094,7 @@ if_down(struct ifnet *ifp)
carp_carpdev_state(ifp);
#endif
#if NBRIDGE > 0
- if (ifp->if_bridge)
+ if (ifp->if_bridgeport)
bstp_ifstate(ifp);
#endif
rt_ifmsg(ifp);
@@ -1130,7 +1130,7 @@ if_up(struct ifnet *ifp)
carp_carpdev_state(ifp);
#endif
#if NBRIDGE > 0
- if (ifp->if_bridge)
+ if (ifp->if_bridgeport)
bstp_ifstate(ifp);
#endif
rt_ifmsg(ifp);
diff --git a/sys/net/if.h b/sys/net/if.h
index ee2d8e88a38..96303d2db84 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.h,v 1.134 2012/09/19 15:29:53 henning Exp $ */
+/* $OpenBSD: if.h,v 1.135 2012/10/05 17:17:04 camield Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -270,7 +270,7 @@ struct ifnet { /* and the entries */
char if_xname[IFNAMSIZ]; /* external name (name + unit) */
int if_pcount; /* number of promiscuous listeners */
caddr_t if_bpf; /* packet filter structure */
- caddr_t if_bridge; /* bridge structure */
+ caddr_t if_bridgeport; /* used by bridge ports */
caddr_t if_tp; /* used by trunk ports */
caddr_t if_pf_kif; /* pf interface abstraction */
union {
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;
diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h
index 68f3047b1f2..3c560ab1b61 100644
--- a/sys/net/if_bridge.h
+++ b/sys/net/if_bridge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.h,v 1.35 2012/09/20 14:10:18 mpf Exp $ */
+/* $OpenBSD: if_bridge.h,v 1.36 2012/10/05 17:17:04 camield Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -384,6 +384,7 @@ struct bstp_state {
*/
struct bridge_iflist {
LIST_ENTRY(bridge_iflist) next; /* next in list */
+ struct bridge_softc *bridge_sc;
struct bstp_port *bif_stp; /* STP port state */
struct brl_head bif_brlin; /* input rules */
struct brl_head bif_brlout; /* output rules */
@@ -392,6 +393,10 @@ struct bridge_iflist {
};
#define bif_state bif_stp->bp_state
+#define SAME_BRIDGE(_bp1, _bp2) \
+ (_bp1 && _bp2 && ((struct bridge_iflist *)_bp1)->bridge_sc == \
+ ((struct bridge_iflist *)_bp2)->bridge_sc)
+
/*
* Bridge route node
*/
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 477fd7018b5..660d9210ec5 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.151 2011/07/09 00:47:18 henning Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.152 2012/10/05 17:17:04 camield Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -379,15 +379,14 @@ ether_output(ifp0, m0, dst, rt0)
#if NBRIDGE > 0
/*
- * Interfaces that are bridge members need special handling
- * for output.
+ * Interfaces that are bridgeports need special handling for output.
*/
- if (ifp->if_bridge) {
+ if (ifp->if_bridgeport) {
struct m_tag *mtag;
/*
* Check if this packet has already been sent out through
- * this bridge, in which case we simply send it out
+ * this bridgeport, in which case we simply send it out
* without further bridge processing.
*/
for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
@@ -399,7 +398,7 @@ ether_output(ifp0, m0, dst, rt0)
goto bad;
}
#endif
- if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)))
+ if (!bcmp(&ifp->if_bridgeport, mtag + 1, sizeof(caddr_t)))
break;
}
if (mtag == NULL) {
@@ -410,7 +409,7 @@ ether_output(ifp0, m0, dst, rt0)
error = ENOBUFS;
goto bad;
}
- bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t));
+ bcopy(&ifp->if_bridgeport, mtag + 1, sizeof(caddr_t));
m_tag_prepend(m, mtag);
error = bridge_output(ifp, m, NULL, NULL);
return (error);
@@ -560,7 +559,7 @@ ether_input(ifp0, eh, m)
* NULL if it has consumed the packet, otherwise, it
* gets processed as normal.
*/
- if (ifp->if_bridge) {
+ if (ifp->if_bridgeport) {
if (m->m_flags & M_PROTO1)
m->m_flags &= ~M_PROTO1;
else {
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 5f49625041b..3407d23591f 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gif.c,v 1.57 2012/05/12 12:58:16 mpf Exp $ */
+/* $OpenBSD: if_gif.c,v 1.58 2012/10/05 17:17:04 camield Exp $ */
/* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */
/*
@@ -176,7 +176,7 @@ gif_start(struct ifnet *ifp)
* the start function and bypasses the if_output function
* so we need to do the encap here.
*/
- if (ifp->if_bridge && (m->m_flags & M_PROTO1)) {
+ if (ifp->if_bridgeport && (m->m_flags & M_PROTO1)) {
int error = 0;
/*
* Remove multicast and broadcast flags or encapsulated