summaryrefslogtreecommitdiffstats
path: root/sys/net/bridge.c
diff options
context:
space:
mode:
authorhsu <hsu@FreeBSD.org>2002-12-22 05:35:03 +0000
committerhsu <hsu@FreeBSD.org>2002-12-22 05:35:03 +0000
commit82e1e3bab0d3abe1018a0b56559c154485f2f676 (patch)
treed0f9ee7e6f9d8014e6f8f94ab6965e85c268792e /sys/net/bridge.c
parent2afef11c570b7b725c3145fc710f8dcd8d7ed4e0 (diff)
downloadFreeBSD-src-82e1e3bab0d3abe1018a0b56559c154485f2f676.zip
FreeBSD-src-82e1e3bab0d3abe1018a0b56559c154485f2f676.tar.gz
SMP locking for ifnet list.
Diffstat (limited to 'sys/net/bridge.c')
-rw-r--r--sys/net/bridge.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/sys/net/bridge.c b/sys/net/bridge.c
index 295c208..13c36cd 100644
--- a/sys/net/bridge.c
+++ b/sys/net/bridge.c
@@ -302,6 +302,7 @@ bridge_off(void)
int i, s;
DEB(printf("bridge_off: n_clusters %d\n", n_clusters);)
+ IFNET_RLOCK();
TAILQ_FOREACH(ifp, &ifnet, if_link) {
struct bdg_softc *b;
@@ -322,6 +323,7 @@ bridge_off(void)
b->cluster = NULL;
bdg_stats.s[ifp->if_index].name[0] = '\0';
}
+ IFNET_RUNLOCK();
/* flush_tables */
s = splimp();
@@ -345,6 +347,7 @@ bridge_on(void)
struct ifnet *ifp ;
int s ;
+ IFNET_RLOCK();
TAILQ_FOREACH(ifp, &ifnet, if_link) {
struct bdg_softc *b = &ifp2sc[ifp->if_index];
@@ -370,6 +373,7 @@ bridge_on(void)
b->flags &= ~IFF_MUTE;
}
}
+ IFNET_RUNLOCK();
}
/**
@@ -435,6 +439,7 @@ parse_bdg_cfg()
/*
* now search in interface list for a matching name
*/
+ IFNET_RLOCK(); /* could sleep XXX */
TAILQ_FOREACH(ifp, &ifnet, if_link) {
char buf[IFNAMSIZ];
@@ -460,6 +465,7 @@ parse_bdg_cfg()
break ;
}
}
+ IFNET_RUNLOCK();
if (!found)
printf("interface %s Not found in bridge\n", beg);
*p = c;
@@ -847,17 +853,10 @@ bdg_forward(struct mbuf *m0, struct ifnet *dst)
printf("xx ouch, bdg_forward for local pkt\n");
return m0;
}
- if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_UNKNOWN) {
- ifp = TAILQ_FIRST(&ifnet) ; /* scan all ports */
- once = 0 ;
- if (dst != BDG_UNKNOWN) /* need a copy for the local stack */
- shared = 1 ;
- } else {
- ifp = dst ;
- once = 1 ;
+ if (dst == BDG_BCAST || dst == BDG_MCAST) {
+ /* need a copy for the local stack */
+ shared = 1 ;
}
- if ((uintptr_t)(ifp) <= (u_int)BDG_FORWARD)
- panic("bdg_forward: bad dst");
/*
* Do filtering in a very similar way to what is done in ip_output.
@@ -1023,6 +1022,17 @@ forward:
real_dst = src ;
last = NULL;
+ IFNET_RLOCK();
+ if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_UNKNOWN) {
+ ifp = TAILQ_FIRST(&ifnet) ; /* scan all ports */
+ once = 0 ;
+ } else {
+ ifp = dst ;
+ once = 1 ;
+ }
+ if ((uintptr_t)(ifp) <= (u_int)BDG_FORWARD)
+ panic("bdg_forward: bad dst");
+
for (;;) {
if (last) { /* need to forward packet leftover from previous loop */
struct mbuf *m ;
@@ -1032,6 +1042,7 @@ forward:
} else {
m = m_copypacket(m0, M_DONTWAIT);
if (m == NULL) {
+ IFNET_RUNLOCK();
printf("bdg_forward: sorry, m_copypacket failed!\n");
bdg_dropped++ ;
return m0 ; /* the original is still there... */
@@ -1062,6 +1073,7 @@ forward:
if (ifp == NULL)
once = 1 ;
}
+ IFNET_RUNLOCK();
DEB(bdg_fw_ticks += (u_long)(rdtsc() - ticks) ; bdg_fw_count++ ;
if (bdg_fw_count != 0) bdg_fw_avg = bdg_fw_ticks/bdg_fw_count; )
return m0 ;
OpenPOWER on IntegriCloud