summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1999-05-24 23:09:12 +0000
committerJason Wright <jason@cvs.openbsd.org>1999-05-24 23:09:12 +0000
commit8337fe0f9b1f07061deb94b937c2bc9ef840c067 (patch)
tree4fb50e82017e05ca85e4cad964b55c4908c47168 /sys
parent1a875079809eb31d2a080e005d76f4f634ebb771 (diff)
Only do basic work in the ethernet interrupt context, and queue packets to
be bridged. Do the real work in a scheduled netisr.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/alpha/alpha/machdep.c6
-rw-r--r--sys/arch/amiga/amiga/machdep.c9
-rw-r--r--sys/arch/arc/arc/trap.c9
-rw-r--r--sys/arch/atari/atari/machdep.c7
-rw-r--r--sys/arch/hp300/hp300/intr.c9
-rw-r--r--sys/arch/i386/isa/icu.s6
-rw-r--r--sys/arch/kbus/kbus/intr.c4
-rw-r--r--sys/arch/mac68k/mac68k/machdep.c9
-rw-r--r--sys/arch/mvme68k/mvme68k/machdep.c9
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c9
-rw-r--r--sys/arch/pc532/pc532/intr.c6
-rw-r--r--sys/arch/pmax/pmax/trap.c9
-rw-r--r--sys/arch/powerpc/powerpc/machdep.c7
-rw-r--r--sys/arch/sparc/sparc/intr.c5
-rw-r--r--sys/arch/sun3/sun3/isr.c9
-rw-r--r--sys/arch/vax/vax/machdep.c8
-rw-r--r--sys/arch/wgrisc/wgrisc/trap.c11
-rw-r--r--sys/net/if_bridge.c474
-rw-r--r--sys/net/netisr.h4
19 files changed, 377 insertions, 233 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index 50facc3c27e..4281760f068 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.27 1999/05/22 21:22:17 weingart Exp $ */
+/* $OpenBSD: machdep.c,v 1.28 1999/05/24 23:08:55 jason Exp $ */
/* $NetBSD: machdep.c,v 1.61 1996/12/07 01:54:49 cgd Exp $ */
/*
@@ -96,6 +96,7 @@
#include <netinet/ip_var.h>
#endif
#include "ppp.h"
+#include "bridge.h"
#include "le_ioasic.h" /* for le_iomem creation */
@@ -1493,6 +1494,9 @@ netintr()
#if NPPP > 0
DONETISR(NETISR_PPP, pppintr());
#endif
+#if NBRIDGE > 0
+ DONETISR(NETISR_BRIDGE, bridgeintr());
+#endif
#undef DONETISR
}
diff --git a/sys/arch/amiga/amiga/machdep.c b/sys/arch/amiga/amiga/machdep.c
index e9de602d790..6bd3da26b44 100644
--- a/sys/arch/amiga/amiga/machdep.c
+++ b/sys/arch/amiga/amiga/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.32 1999/05/22 21:22:18 weingart Exp $ */
+/* $OpenBSD: machdep.c,v 1.33 1999/05/24 23:08:58 jason Exp $ */
/* $NetBSD: machdep.c,v 1.95 1997/08/27 18:31:17 is Exp $ */
/*
@@ -108,6 +108,7 @@
#include "ser.h"
#include "ether.h"
#include "ppp.h"
+#include "bridge.h"
#include <net/if.h>
@@ -1230,6 +1231,12 @@ netintr()
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
diff --git a/sys/arch/arc/arc/trap.c b/sys/arch/arc/arc/trap.c
index 31f79200047..edb0e8c0fea 100644
--- a/sys/arch/arc/arc/trap.c
+++ b/sys/arch/arc/arc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.21 1999/01/07 23:15:55 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.22 1999/05/24 23:08:59 jason Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -43,6 +43,7 @@
*/
#include "ppp.h"
+#include "bridge.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -919,6 +920,12 @@ interrupt(statusReg, causeReg, what, pc, args)
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if(netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
if (mask & SOFT_INT_MASK_0) {
clearsoftclock();
diff --git a/sys/arch/atari/atari/machdep.c b/sys/arch/atari/atari/machdep.c
index 8bebb10f257..01e18c172ac 100644
--- a/sys/arch/atari/atari/machdep.c
+++ b/sys/arch/atari/atari/machdep.c
@@ -90,6 +90,7 @@
#include "ether.h"
#include "ppp.h"
+#include "bridge.h"
static void call_sicallbacks __P((void));
static void alloc_sicallback __P((void));
@@ -1139,6 +1140,12 @@ netintr()
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
diff --git a/sys/arch/hp300/hp300/intr.c b/sys/arch/hp300/hp300/intr.c
index a8db5915ce9..a73ea086e65 100644
--- a/sys/arch/hp300/hp300/intr.c
+++ b/sys/arch/hp300/hp300/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.4 1999/01/11 05:11:20 millert Exp $ */
+/* $OpenBSD: intr.c,v 1.5 1999/05/24 23:09:00 jason Exp $ */
/* $NetBSD: intr.c,v 1.2 1997/05/01 16:24:26 thorpej Exp $ */
/*-
@@ -50,6 +50,7 @@
#include <net/netisr.h>
#include "ppp.h"
+#include "bridge.h"
void netintr __P((void));
@@ -329,4 +330,10 @@ netintr()
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
diff --git a/sys/arch/i386/isa/icu.s b/sys/arch/i386/isa/icu.s
index 046b436a067..bb65eb051df 100644
--- a/sys/arch/i386/isa/icu.s
+++ b/sys/arch/i386/isa/icu.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: icu.s,v 1.10 1999/01/07 23:15:58 deraadt Exp $ */
+/* $OpenBSD: icu.s,v 1.11 1999/05/24 23:09:01 jason Exp $ */
/* $NetBSD: icu.s,v 1.45 1996/01/07 03:59:34 mycroft Exp $ */
/*-
@@ -185,6 +185,10 @@ IDTVEC(softnet)
#if NPPP > 0
DONET(NETISR_PPP, _pppintr)
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ DONET(NETISR_BRIDGE, _bridgeintr)
+#endif
movl %ebx,_cpl
jmp %esi
diff --git a/sys/arch/kbus/kbus/intr.c b/sys/arch/kbus/kbus/intr.c
index f506c3308e2..bbdef71399e 100644
--- a/sys/arch/kbus/kbus/intr.c
+++ b/sys/arch/kbus/kbus/intr.c
@@ -45,6 +45,7 @@
*/
#include "ppp.h"
+#include "bridge.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -163,6 +164,9 @@ netintr()
#if NPPP > 1
DONETISR(NETISR_PPP, pppintr());
#endif
+#if NBRIDGE > 1
+ DONETISR(NETISR_BRIDGE, bridgeintr());
+#endif
#undef DONETISR
}
diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c
index 4186f788d90..f28dc5559dc 100644
--- a/sys/arch/mac68k/mac68k/machdep.c
+++ b/sys/arch/mac68k/mac68k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.60 1999/05/23 06:55:06 downsj Exp $ */
+/* $OpenBSD: machdep.c,v 1.61 1999/05/24 23:09:03 jason Exp $ */
/* $NetBSD: machdep.c,v 1.134 1997/02/14 06:15:30 scottr Exp $ */
/*
@@ -1064,6 +1064,13 @@ netintr()
pppintr();
}
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
/*
diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c
index 3d7ebc53607..96564c7b469 100644
--- a/sys/arch/mvme68k/mvme68k/machdep.c
+++ b/sys/arch/mvme68k/mvme68k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.26 1999/05/22 21:22:26 weingart Exp $ */
+/* $OpenBSD: machdep.c,v 1.27 1999/05/24 23:09:04 jason Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -904,6 +904,13 @@ netintr()
pppintr();
}
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
/*
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index 27085bb3023..a5ced81862b 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.13 1999/05/22 21:22:27 weingart Exp $ */
+/* $OpenBSD: machdep.c,v 1.14 1999/05/24 23:09:05 jason Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -1617,6 +1617,13 @@ void netintr()
pppintr();
}
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
void
diff --git a/sys/arch/pc532/pc532/intr.c b/sys/arch/pc532/pc532/intr.c
index 0f95204b7bf..afe3d85ea4b 100644
--- a/sys/arch/pc532/pc532/intr.c
+++ b/sys/arch/pc532/pc532/intr.c
@@ -29,7 +29,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: intr.c,v 1.3 1997/07/23 06:58:24 denny Exp $
+ * $Id: intr.c,v 1.4 1999/05/24 23:09:06 jason Exp $
*/
#define DEFINE_SPLX
@@ -196,6 +196,10 @@ softnet()
#if NPPP > 0
if (isr & (1 << NETISR_PPP)) pppintr();
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ if (isr & (1 << NETISR_BRIDGE)) bridgeintr();
+#endif
}
/*
diff --git a/sys/arch/pmax/pmax/trap.c b/sys/arch/pmax/pmax/trap.c
index a123d22f5ff..41c3b6208bc 100644
--- a/sys/arch/pmax/pmax/trap.c
+++ b/sys/arch/pmax/pmax/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.19 1999/05/22 10:01:09 maja Exp $ */
+/* $OpenBSD: trap.c,v 1.20 1999/05/24 23:09:06 jason Exp $ */
/* $NetBSD: trap.c,v 1.50 1996/10/13 21:37:49 jonathan Exp $ */
/*
@@ -80,6 +80,7 @@
#include <miscfs/procfs/procfs.h>
#include "ppp.h"
+#include "bridge.h"
struct proc *machFPCurProcPtr; /* pointer to last proc to use FP */
@@ -1084,6 +1085,12 @@ interrupt(statusReg, causeReg, pc /* XXX what, args */ )
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
if (mask & MIPS_SOFT_INT_MASK_0) {
diff --git a/sys/arch/powerpc/powerpc/machdep.c b/sys/arch/powerpc/powerpc/machdep.c
index d2d1037e04b..a7b9d6c6772 100644
--- a/sys/arch/powerpc/powerpc/machdep.c
+++ b/sys/arch/powerpc/powerpc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.23 1999/05/22 21:22:29 weingart Exp $ */
+/* $OpenBSD: machdep.c,v 1.24 1999/05/24 23:09:07 jason Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -715,6 +715,11 @@ softnet(isr)
if (isr & (1 << NETISR_PPP))
pppintr();
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ if (isr & (1 << NETISR_BRIDGE))
+ bridgeintr();
+#endif
}
void
diff --git a/sys/arch/sparc/sparc/intr.c b/sys/arch/sparc/sparc/intr.c
index 9cbdbb17b6f..95a7b6ed4de 100644
--- a/sys/arch/sparc/sparc/intr.c
+++ b/sys/arch/sparc/sparc/intr.c
@@ -67,6 +67,7 @@
#include <netinet/ip_var.h>
#endif
#include "ppp.h"
+#include "bridge.h"
void strayintr __P((struct clockframe *));
int soft01intr __P((void *));
@@ -156,6 +157,10 @@ soft01intr(fp)
if (n & (1 << NETISR_PPP))
pppintr();
#endif
+#if NBRIDGE > 0
+ if (n & (1 << NETISR_BRIDGE))
+ bridgeintr();
+#endif
}
if (sir.sir_which[SIR_CLOCK]) {
sir.sir_which[SIR_CLOCK] = 0;
diff --git a/sys/arch/sun3/sun3/isr.c b/sys/arch/sun3/sun3/isr.c
index d6d4419f710..10ad3d52620 100644
--- a/sys/arch/sun3/sun3/isr.c
+++ b/sys/arch/sun3/sun3/isr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isr.c,v 1.8 1999/01/11 05:12:06 millert Exp $ */
+/* $OpenBSD: isr.c,v 1.9 1999/05/24 23:09:08 jason Exp $ */
/* $NetBSD: isr.c,v 1.25 1996/11/20 18:57:32 gwr Exp $ */
/*-
@@ -60,6 +60,7 @@
#include "ether.h" /* for NETHER */
#include "ppp.h" /* for NPPP */
+#include "bridge.h" /* for NBRIDGE */
extern int intrcnt[]; /* statistics */
@@ -105,6 +106,7 @@ void nsintr __P((void));
void clnlintr __P((void));
void ccittintr __P((void));
void pppintr __P((void));
+void bridgeintr __P((void));
void
netintr()
@@ -146,6 +148,11 @@ netintr()
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if (n & (1 << NETISR_BRIDGE)) {
+ bridgeintr();
+ }
+#endif
}
diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c
index 2ea640c80eb..f63eaec3d57 100644
--- a/sys/arch/vax/vax/machdep.c
+++ b/sys/arch/vax/vax/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.18 1999/05/22 21:22:32 weingart Exp $ */
+/* $OpenBSD: machdep.c,v 1.19 1999/05/24 23:09:09 jason Exp $ */
/* $NetBSD: machdep.c,v 1.45 1997/07/26 10:12:49 ragge Exp $ */
/*
@@ -90,6 +90,7 @@
#include <netns/ns_var.h>
#endif
#include "ppp.h" /* For NERISR_PPP */
+#include "bridge.h" /* For NERISR_BRIDGE */
#if NPPP > 0
#include <net/ppp_defs.h>
#include <net/if_ppp.h>
@@ -722,6 +723,11 @@ netintr()
pppintr();
}
#endif
+#if NBRIDGE > 0
+ if (netisr & (1 << NETISR_BRIDGE)) {
+ bridgeintr();
+ }
+#endif
}
void
diff --git a/sys/arch/wgrisc/wgrisc/trap.c b/sys/arch/wgrisc/wgrisc/trap.c
index 035476d1dbf..7b04ac9aa3f 100644
--- a/sys/arch/wgrisc/wgrisc/trap.c
+++ b/sys/arch/wgrisc/wgrisc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.3 1999/01/08 00:03:00 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.4 1999/05/24 23:09:10 jason Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1992, 1993
@@ -39,7 +39,7 @@
* from: Utah Hdr: trap.c 1.32 91/04/06
*
* from: @(#)trap.c 8.5 (Berkeley) 1/11/94
- * $Id: trap.c,v 1.3 1999/01/08 00:03:00 deraadt Exp $
+ * $Id: trap.c,v 1.4 1999/05/24 23:09:10 jason Exp $
*/
#include <sys/param.h>
@@ -1041,6 +1041,13 @@ interrupt(statusReg, causeReg, pc, what, args)
pppintr();
}
#endif
+#include "bridge.h"
+#if NBRIDGE > 0
+ if(netisr & (1 << NETISR_BRIDGE)) {
+ netisr &= ~(1 << NETISR_BRIDGE);
+ bridgeintr();
+ }
+#endif
}
if (mask & SOFT_INT_MASK_0) {
clearsoftclock();
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 1038df0c081..f014bd5847c 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.8 1999/03/19 22:47:33 jason Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.9 1999/05/24 23:09:10 jason Exp $ */
/*
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
@@ -48,6 +48,7 @@
#include <net/if_types.h>
#include <net/if_llc.h>
#include <net/route.h>
+#include <net/netisr.h>
#ifdef INET
#include <netinet/in.h>
@@ -118,7 +119,7 @@ struct bridge_softc {
struct ifnet sc_if; /* the interface */
u_int32_t sc_brtmax; /* max # addresses */
u_int32_t sc_brtcnt; /* current # addrs */
- u_int32_t sc_brttimeout; /* current # addrs */
+ u_int32_t sc_brttimeout; /* timeout ticks */
LIST_HEAD(, bridge_iflist) sc_iflist; /* interface list */
LIST_HEAD(bridge_rthead, bridge_rtnode) *sc_rts;/* hash table */
};
@@ -180,7 +181,7 @@ bridgeattach(unused)
ifp->if_ioctl = bridge_ioctl;
ifp->if_output = bridge_output;
ifp->if_start = bridge_start;
- ifp->if_type = IFT_PROPVIRTUAL;
+ ifp->if_type = IFT_PROPVIRTUAL;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_hdrlen = sizeof(struct ether_header);
if_attach(ifp);
@@ -190,7 +191,7 @@ bridgeattach(unused)
int
bridge_ioctl(ifp, cmd, data)
struct ifnet *ifp;
- u_long cmd;
+ u_long cmd;
caddr_t data;
{
struct proc *prc = curproc; /* XXX */
@@ -207,7 +208,7 @@ bridge_ioctl(ifp, cmd, data)
struct bridge_iflist *p;
s = splimp();
- switch(cmd) {
+ switch (cmd) {
case SIOCBRDGADD:
if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
break;
@@ -217,17 +218,14 @@ bridge_ioctl(ifp, cmd, data)
error = ENOENT;
break;
}
-
if (ifs->if_bridge == (caddr_t)sc) {
error = EEXIST;
break;
}
-
if (ifs->if_bridge != NULL) {
error = EBUSY;
break;
}
-
if (ifs->if_type != IFT_ETHER) {
error = EINVAL;
break;
@@ -252,7 +250,6 @@ bridge_ioctl(ifp, cmd, data)
if (error != 0)
break;
-
strncpy(ifreq.ifr_name, req->ifbr_ifsname,
sizeof(ifreq.ifr_name) - 1);
ifreq.ifr_name[sizeof(ifreq.ifr_name) - 1] = '\0';
@@ -264,8 +261,7 @@ bridge_ioctl(ifp, cmd, data)
ifpromisc(ifs, 0);
break;
}
- }
- else {
+ } else {
error = ifpromisc(ifs, 1);
if (error != 0)
break;
@@ -460,11 +456,11 @@ bridge_bifconf(sc, bifc)
i = 0;
while (p != NULL && bifc->ifbic_len > sizeof(breq)) {
strncpy(breq.ifbr_name, sc->sc_if.if_xname,
- sizeof (breq.ifbr_name));
- breq.ifbr_name[sizeof(breq.ifbr_name)-1] = '\0';
+ sizeof(breq.ifbr_name));
+ breq.ifbr_name[sizeof(breq.ifbr_name) - 1] = '\0';
strncpy(breq.ifbr_ifsname, p->ifp->if_xname,
- sizeof (breq.ifbr_ifsname));
- breq.ifbr_ifsname[sizeof(breq.ifbr_ifsname)-1] = '\0';
+ sizeof(breq.ifbr_ifsname));
+ breq.ifbr_ifsname[sizeof(breq.ifbr_ifsname) - 1] = '\0';
breq.ifbr_ifsflags = p->bif_flags;
error = copyout((caddr_t)&breq,
(caddr_t)(bifc->ifbic_req + i), sizeof(breq));
@@ -485,8 +481,7 @@ bridge_init(sc)
struct bridge_softc *sc;
{
struct ifnet *ifp = &sc->sc_if;
- int i;
- int s;
+ int i, s;
if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING)
return;
@@ -500,7 +495,6 @@ bridge_init(sc)
splx(s);
return;
}
-
for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
LIST_INIT(&sc->sc_rts[i]);
}
@@ -673,6 +667,162 @@ bridge_start(ifp)
}
/*
+ * Loop through each bridge interface and process their input queues.
+ */
+void
+bridgeintr(void)
+{
+ int i, s;
+ struct bridge_softc *sc;
+ struct ifnet *bifp, *src_if, *dst_if;
+ struct bridge_iflist *ifl;
+ struct ether_addr *dst, *src;
+ struct ether_header *eh;
+ struct mbuf *m;
+
+ for (i = 0; i < NBRIDGE; i++) {
+ sc = &bridgectl[i];
+ bifp = &sc->sc_if;
+ for (;;) {
+ s = splimp();
+ IF_DEQUEUE(&bifp->if_snd, m);
+ splx(s);
+ if (m == NULL)
+ break;
+
+ src_if = m->m_pkthdr.rcvif;
+ if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
+ m_freem(m);
+ continue;
+ }
+
+ sc->sc_if.if_lastchange = time;
+ sc->sc_if.if_ipackets++;
+ sc->sc_if.if_ibytes += m->m_pkthdr.len;
+
+ ifl = LIST_FIRST(&sc->sc_iflist);
+ while (ifl != NULL && ifl->ifp != src_if) {
+ ifl = LIST_NEXT(ifl, next);
+ }
+ if (ifl == NULL) {
+ m_freem(m);
+ continue;
+ }
+
+ if (m->m_len < sizeof(*eh)) {
+ m = m_pullup(m, sizeof(*eh));
+ if (m == NULL)
+ continue;
+ }
+ eh = mtod(m, struct ether_header *);
+ dst = (struct ether_addr *)&eh->ether_dhost[0];
+ src = (struct ether_addr *)&eh->ether_shost[0];
+
+ /*
+ * If interface is learning, and if source address
+ * is not broadcast or multicast, record it's address.
+ */
+ if ((ifl->bif_flags & IFBIF_LEARNING) &&
+ (eh->ether_shost[0] & 1) == 0 &&
+ !(eh->ether_shost[0] == 0 &&
+ eh->ether_shost[1] == 0 &&
+ eh->ether_shost[2] == 0 &&
+ eh->ether_shost[3] == 0 &&
+ eh->ether_shost[4] == 0 &&
+ eh->ether_shost[5] == 0))
+ bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC);
+
+ /*
+ * If packet is unicast, destined for someone on "this"
+ * side of the bridge, drop it.
+ */
+ dst_if = bridge_rtlookup(sc, dst);
+ if ((m->m_flags & (M_BCAST | M_MCAST)) == 0 &&
+ dst_if == src_if) {
+ m_freem(m);
+ continue;
+ }
+
+ /*
+ * Multicast packets get handled a little differently:
+ * If interface is:
+ * -link0,-link1 (default) Forward all multicast
+ * as broadcast.
+ * -link0,link1 Drop non-IP multicast, forward
+ * as broadcast IP multicast.
+ * link0,-link1 Drop IP multicast, forward as
+ * broadcast non-IP multicast.
+ * link0,link1 Drop all multicast.
+ */
+ if (m->m_flags & M_MCAST) {
+ if ((sc->sc_if.if_flags &
+ (IFF_LINK0 | IFF_LINK1)) ==
+ (IFF_LINK0 | IFF_LINK1)) {
+ m_freem(m);
+ continue;
+ }
+ if (sc->sc_if.if_flags & IFF_LINK0 &&
+ ETHERADDR_IS_IP_MCAST(dst)) {
+ m_freem(m);
+ continue;
+ }
+ if (sc->sc_if.if_flags & IFF_LINK1 &&
+ !ETHERADDR_IS_IP_MCAST(dst)) {
+ m_freem(m);
+ continue;
+ }
+ }
+
+#if defined(INET) && (defined(IPFILTER) || defined(IPFILTER_LKM))
+ if (bridge_filter(sc, src_if, eh, &m) ==
+ BRIDGE_FILTER_DROP) {
+ if (m != NULL)
+ m_freem(m);
+ continue;
+ }
+#endif
+ /*
+ * If the packet is a multicast or broadcast, then
+ * forward it and pass it up to our higher layers.
+ */
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ bifp->if_imcasts++;
+ m = bridge_broadcast(sc, src_if, eh, m);
+ if (m != NULL)
+ m_freem(m);
+ continue;
+ }
+
+ if (dst_if != NULL) {
+ if ((dst_if->if_flags & IFF_RUNNING) == 0) {
+ m_freem(m);
+ continue;
+ }
+ s = splimp();
+ if (IF_QFULL(&dst_if->if_snd)) {
+ sc->sc_if.if_oerrors++;
+ m_freem(m);
+ splx(s);
+ continue;
+ }
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&dst_if->if_snd, m);
+ if ((dst_if->if_flags & IFF_OACTIVE) == 0)
+ (*dst_if->if_start)(dst_if);
+ splx(s);
+ continue;
+ }
+
+ m = bridge_broadcast(sc, src_if, eh, m);
+ dst_if = NULL;
+ if (m != NULL)
+ m_freem(m);
+ }
+ }
+}
+
+/*
* Receive input from an interface. Rebroadcast if necessary to other
* bridge members.
*/
@@ -683,11 +833,11 @@ bridge_input(ifp, eh, m)
struct mbuf *m;
{
struct bridge_softc *sc;
- struct arpcom *ac;
- struct ether_addr *dst, *src;
- struct ifnet *dst_if;
- struct bridge_iflist *ifl;
int s;
+ struct bridge_iflist *ifl;
+ struct arpcom *ac;
+ struct ether_header *neh;
+ struct mbuf *mc;
/*
* Make sure this interface is a bridge member.
@@ -696,167 +846,59 @@ bridge_input(ifp, eh, m)
return (m);
sc = (struct bridge_softc *)ifp->if_bridge;
-
- s = splimp();
-
- if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
- splx(s);
- return (m);
- }
-
- sc->sc_if.if_lastchange = time;
- sc->sc_if.if_ipackets++;
- sc->sc_if.if_ibytes += m->m_pkthdr.len;
-
- /*
- * See if the destination of this frame matches the interface
- * it came in on. If so, we don't need to do anything.
- */
- ac = (struct arpcom *)ifp;
- if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0) {
- splx(s);
- return (m);
- }
-
- dst = (struct ether_addr *)&eh->ether_dhost[0];
- src = (struct ether_addr *)&eh->ether_shost[0];
-
- ifl = LIST_FIRST(&sc->sc_iflist);
- while (ifl != NULL && ifl->ifp != ifp) {
- ifl = LIST_NEXT(ifl, next);
- }
- if (ifl == NULL) {
- splx(s);
+ if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
return (m);
- }
- /*
- * If interface is learning, and if source address is not broadcast
- * or multicast, record it's address.
- */
- if ((ifl->bif_flags & IFBIF_LEARNING) &&
- (eh->ether_shost[0] & 1) == 0 &&
- !(eh->ether_shost[0] == 0 && eh->ether_shost[1] == 0 &&
- eh->ether_shost[2] == 0 && eh->ether_shost[3] == 0 &&
- eh->ether_shost[4] == 0 && eh->ether_shost[5] == 0))
- bridge_rtupdate(sc, src, ifp, 0, IFBAF_DYNAMIC);
-
- /*
- * If packet is unicast, destined for someone on "this"
- * side of the bridge, drop it.
- */
- dst_if = bridge_rtlookup(sc, dst);
- if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 && dst_if == ifp) {
- m_freem(m);
- splx(s);
- return (NULL);
- }
-
- /*
- * Multicast packets get handled a little differently:
- * If interface is:
- * -link0,-link1 (default) Forward all multicast as broadcast.
- * -link0,link1 Drop non-IP multicast, forward as broadcast
- * IP multicast.
- * link0,-link1 Drop IP multicast, forward as broadcast
- * non-IP multicast.
- * link0,link1 Drop all multicast.
- */
- if (m->m_flags & M_MCAST) {
- if ((sc->sc_if.if_flags & (IFF_LINK0|IFF_LINK1)) ==
- (IFF_LINK0|IFF_LINK1)) {
- splx(s);
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ /* make a copy of 'm' with 'eh' tacked on to the
+ * beginning. Return 'm' for local processing
+ * and enqueue the copy. Schedule netisr.
+ */
+ mc = m_copym2(m, 0, M_COPYALL, M_NOWAIT);
+ if (mc == NULL)
return (m);
- }
- if (sc->sc_if.if_flags & IFF_LINK0 &&
- ETHERADDR_IS_IP_MCAST(dst)) {
- splx(s);
+ M_PREPEND(mc, sizeof(*eh), M_DONTWAIT);
+ if (mc == NULL)
return (m);
- }
- if (sc->sc_if.if_flags & IFF_LINK1 &&
- !ETHERADDR_IS_IP_MCAST(dst)) {
+ neh = mtod(mc, struct ether_header *);
+ bcopy(eh, neh, sizeof(struct ether_header));
+ s = splimp();
+ if (IF_QFULL(&sc->sc_if.if_snd)) {
+ m_freem(mc);
splx(s);
return (m);
}
- }
-
-#if defined(INET) && (defined(IPFILTER) || defined(IPFILTER_LKM))
- /*
- * Pass the packet to the ip filtering code and drop
- * here if necessary.
- */
- if (bridge_filter(sc, ifp, eh, &m) == BRIDGE_FILTER_DROP) {
- if (m == NULL || m->m_flags & (M_BCAST|M_MCAST)) {
- /*
- * Broadcasts should be passed down if filtered
- * by the bridge, so that they can be filtered
- * by the interface itself.
- */
- splx(s);
- return (m);
- }
- m_freem(m);
- splx(s);
- return (NULL);
- }
- if (m == NULL) {
- splx(s);
- return (NULL);
- }
-#endif
-
- /*
- * If the packet is a multicast or broadcast, then forward it
- * and pass it up to our higher layers.
- */
- if (m->m_flags & (M_BCAST|M_MCAST)) {
- ifp->if_imcasts++;
- m = bridge_broadcast(sc, ifp, eh, m);
+ IF_ENQUEUE(&sc->sc_if.if_snd, mc);
splx(s);
+ schednetisr(NETISR_BRIDGE);
return (m);
}
-
- /*
- * If sucessful lookup, forward packet to that interface only.
- */
- if (dst_if != NULL) {
- if ((dst_if->if_flags & IFF_RUNNING) == 0) {
- m_freem(m);
- splx(s);
- return (NULL);
+ else {
+ ifl = LIST_FIRST(&sc->sc_iflist);
+ while (ifl != NULL) {
+ ac = (struct arpcom *)ifl->ifp;
+ if (bcmp(ac->ac_enaddr, eh->ether_dhost,
+ ETHER_ADDR_LEN) == 0) {
+ return (m);
+ }
+ ifl = LIST_NEXT(ifl, next);
}
-
- if (IF_QFULL(&dst_if->if_snd)) {
- sc->sc_if.if_oerrors++;
+ M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
+ if (m == NULL)
+ return (NULL);
+ neh = mtod(m, struct ether_header *);
+ bcopy(eh, neh, sizeof(struct ether_header));
+ s = splimp();
+ if (IF_QFULL(&sc->sc_if.if_snd)) {
m_freem(m);
splx(s);
return (NULL);
}
-
- M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
- if (m == NULL) {
- sc->sc_if.if_oerrors++;
- return (NULL);
- }
- *mtod(m, struct ether_header *) = *eh;
-
- sc->sc_if.if_opackets++;
- sc->sc_if.if_obytes += m->m_pkthdr.len;
-
- IF_ENQUEUE(&dst_if->if_snd, m);
- if ((dst_if->if_flags & IFF_OACTIVE) == 0)
- (*dst_if->if_start)(dst_if);
-
+ IF_ENQUEUE(&sc->sc_if.if_snd, m);
splx(s);
+ schednetisr(NETISR_BRIDGE);
return (NULL);
}
-
- /*
- * Packet must be forwarded to all interfaces.
- */
- m = bridge_broadcast(sc, ifp, eh, m);
- splx(s);
- return (m);
}
/*
@@ -872,15 +914,7 @@ bridge_broadcast(sc, ifp, eh, m)
struct mbuf *m;
{
struct bridge_iflist *p;
- struct mbuf *mc;
-
- /*
- * Tack on ethernet header
- */
- M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
- if (m == NULL)
- return (NULL);
- *mtod(m, struct ether_header *) = *eh;
+ struct mbuf *mc, *ret;
for (p = LIST_FIRST(&sc->sc_iflist); p; p = LIST_NEXT(p, next)) {
/*
@@ -891,7 +925,7 @@ bridge_broadcast(sc, ifp, eh, m)
continue;
if ((p->bif_flags & IFBIF_DISCOVER) == 0 &&
- (m->m_flags & (M_BCAST|M_MCAST)) == 0)
+ (m->m_flags & (M_BCAST | M_MCAST)) == 0)
continue;
if ((p->ifp->if_flags & IFF_RUNNING) == 0)
@@ -902,10 +936,18 @@ bridge_broadcast(sc, ifp, eh, m)
continue;
}
- mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (mc == NULL) {
- sc->sc_if.if_oerrors++;
- continue;
+ /* If last one, reuse the passed-in mbuf */
+ if (LIST_NEXT(p, next) == NULL) {
+ mc = m;
+ ret = NULL;
+ }
+ else {
+ ret = m;
+ mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
+ if (mc == NULL) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
}
sc->sc_if.if_opackets++;
@@ -918,8 +960,7 @@ bridge_broadcast(sc, ifp, eh, m)
(*p->ifp->if_start)(p->ifp);
}
- m_adj(m, sizeof(struct ether_header));
- return (m);
+ return (ret);
}
struct ifnet *
@@ -1245,8 +1286,7 @@ bridge_rtflush(sc)
sc->sc_brtcnt--;
free(n, M_DEVBUF);
n = p;
- }
- else
+ } else
n = LIST_NEXT(n, brt_next);
}
}
@@ -1317,8 +1357,7 @@ bridge_rtdelete(sc, ifp)
sc->sc_brtcnt--;
free(n, M_DEVBUF);
n = p;
- }
- else
+ } else
n = LIST_NEXT(n, brt_next);
}
}
@@ -1363,7 +1402,7 @@ bridge_rtfind(sc, baconf)
return (0);
}
bcopy(sc->sc_if.if_xname, bareq.ifba_name,
- sizeof(bareq.ifba_name));
+ sizeof(bareq.ifba_name));
bcopy(n->brt_if->if_xname, bareq.ifba_ifsname,
sizeof(bareq.ifba_ifsname));
bcopy(&n->brt_addr, &bareq.ifba_dst,
@@ -1389,6 +1428,12 @@ bridge_rtfind(sc, baconf)
}
#if defined(INET) && (defined(IPFILTER) || defined(IPFILTER_LKM))
+
+struct ehllc {
+ struct ether_header eh;
+ struct llc llc;
+};
+
/*
* Filter IP packets by peeking into the ethernet frame. This violates
* the ISO model, but allows us to act as a IP filter at the data link
@@ -1403,46 +1448,47 @@ bridge_filter(sc, ifp, eh, np)
struct mbuf **np;
{
struct mbuf *m = *np;
- struct llc *llc;
+ struct ehllc *ehllc;
struct ip *ip;
u_int16_t etype;
- int hlen, r, off = 0;
+ int hlen, r, off = sizeof(struct ether_header);
if (fr_checkp == NULL)
return (BRIDGE_FILTER_PASS);
- etype = ntohs(eh->ether_type);
+ if (m->m_len < sizeof(struct ehllc)) {
+ m = m_pullup(m, sizeof(struct ehllc));
+ *np = m;
+ if (m == NULL)
+ return (BRIDGE_FILTER_DROP);
+ }
+
+ ehllc = mtod(m, struct ehllc *);
+ etype = ntohs(ehllc->eh.ether_type);
if (etype != ETHERTYPE_IP) {
if (etype > ETHERMTU) /* Can't be SNAP */
return (BRIDGE_FILTER_PASS);
- m = *np;
- if (m->m_len < 8) {
- m = m_pullup(m, 8);
- *np = m;
- if (m == NULL)
- return (BRIDGE_FILTER_DROP);
- }
- llc = mtod(m, struct llc *);
- if (llc->llc_control != LLC_UI ||
- llc->llc_dsap != LLC_SNAP_LSAP ||
- llc->llc_ssap != LLC_SNAP_LSAP ||
- llc->llc_snap.org_code[0] != 0 ||
- llc->llc_snap.org_code[1] != 0 ||
- llc->llc_snap.org_code[2] != 0 ||
- ntohs(llc->llc_snap.ether_type) != ETHERTYPE_IP)
+ if (ehllc->llc.llc_control != LLC_UI ||
+ ehllc->llc.llc_dsap != LLC_SNAP_LSAP ||
+ ehllc->llc.llc_ssap != LLC_SNAP_LSAP ||
+ ehllc->llc.llc_snap.org_code[0] != 0 ||
+ ehllc->llc.llc_snap.org_code[1] != 0 ||
+ ehllc->llc.llc_snap.org_code[2] != 0 ||
+ ntohs(ehllc->llc.llc_snap.ether_type) != ETHERTYPE_IP)
return (BRIDGE_FILTER_PASS);
- off = 8;
+ off += 8;
}
-
/*
* We need a full copy because we're going to be destructive
* to the packet before we pass it to the ip filter code.
* XXX This needs to be turned into a munge -> check ->
* XXX unmunge section, for now, we copy.
+ * XXX Copy at offset 0 so that the mbuf header is copied, too.
*/
- m = m_copym2(m, off, M_COPYALL, M_NOWAIT);
+ m = m_copym2(m, 0, M_COPYALL, M_NOWAIT);
+ m_adj(m, off);
if (m == NULL)
return (BRIDGE_FILTER_DROP);
@@ -1463,12 +1509,12 @@ bridge_filter(sc, ifp, eh, np)
r = BRIDGE_FILTER_DROP;
goto out;
}
+
hlen = ip->ip_hl << 2; /* get whole header length */
if (hlen < sizeof(struct ip)) {
r = BRIDGE_FILTER_DROP;
goto out;
}
-
if (hlen > m->m_len) { /* pull up whole header */
if ((m = m_pullup(m, hlen)) == 0) {
r = BRIDGE_FILTER_DROP;
@@ -1497,18 +1543,12 @@ bridge_filter(sc, ifp, eh, np)
if (m->m_len == m->m_pkthdr.len) {
m->m_len = ip->ip_len;
m->m_pkthdr.len = ip->ip_len;
- }
- else
+ } else
m_adj(m, ip->ip_len - m->m_pkthdr.len);
}
- /*
- * Finally, we get to filter the packet! Pass through
- * once with the bridge as the rcvif, and again with the
- * real receiving interface as rcvif.
- */
- m->m_pkthdr.rcvif = ifp;
- if (fr_checkp && (*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m))
+ /* Finally, we get to filter the packet! */
+ if (fr_checkp && (*fr_checkp)(ip, hlen, ifp, 0, &m))
return (BRIDGE_FILTER_DROP);
r = BRIDGE_FILTER_PASS;
diff --git a/sys/net/netisr.h b/sys/net/netisr.h
index 609b43e2069..4c5914d30da 100644
--- a/sys/net/netisr.h
+++ b/sys/net/netisr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: netisr.h,v 1.12 1999/01/07 23:15:49 deraadt Exp $ */
+/* $OpenBSD: netisr.h,v 1.13 1999/05/24 23:09:11 jason Exp $ */
/* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */
/*
@@ -66,6 +66,7 @@
#define NETISR_ISDN 26 /* same as AF_E164 */
#define NETISR_NATM 27 /* same as AF_ATM */
#define NETISR_PPP 28 /* for PPP processing */
+#define NETISR_BRIDGE 29 /* for bridge processing */
#ifndef _LOCORE
#ifdef _KERNEL
@@ -80,6 +81,7 @@ void clnlintr __P((void));
void natmintr __P((void));
void pppintr __P((void));
void ccittintr __P((void));
+void bridgeintr __P((void));
#include <dev/rndvar.h>
#define schednetisr(anisr) \