diff -urN linux/include/net/br.h linux.bridge/include/net/br.h
--- linux/include/net/br.h	Thu Apr 11 23:49:47 1996
+++ linux.bridge/include/net/br.h	Mon Sep 16 20:11:21 1996
@@ -161,15 +161,29 @@
 
 #define IS_BRIDGED	0x2e
 
+
+#define BR_MAX_PROTOCOLS 32
+#define BR_MAX_PROT_STATS BR_MAX_PROTOCOLS
+
+/* policy values for policy field */
+#define BR_ACCEPT 1
+#define BR_REJECT 0
+
 struct br_stat {
 	unsigned int flags;
 	Bridge_data bridge_data;
 	Port_data port_data[No_of_ports];
+	unsigned int policy;
+	unsigned int exempt_protocols;
+	unsigned short protocols[BR_MAX_PROTOCOLS];
+	unsigned short prot_id[BR_MAX_PROT_STATS];	/* Protocol encountered */
+	unsigned int prot_counter[BR_MAX_PROT_STATS];	/* How many packets ? */
 };
 
 /* defined flags for br_stat.flags */
 #define BR_UP		0x0001	/* bridging enabled */
 #define BR_DEBUG	0x0002	/* debugging enabled */
+#define BR_PROT_STATS	0x0004	/* protocol statistics enabled */
 
 struct br_cf {
 	unsigned int cmd;
@@ -188,6 +202,11 @@
 #define	BRCMD_DISPLAY_FDB	8	/* arg1 = port */
 #define	BRCMD_ENABLE_DEBUG	9
 #define	BRCMD_DISABLE_DEBUG	10
+#define BRCMD_SET_POLICY	11	/* arg1 = default policy (1==bridge all) */
+#define BRCMD_EXEMPT_PROTOCOL	12	/* arg1 = protocol (see net/if_ether.h) */
+#define BRCMD_ENABLE_PROT_STATS	13
+#define BRCMD_DISABLE_PROT_STATS 14
+#define BRCMD_ZERO_PROT_STATS	15
 
 /* prototypes of all bridging functions... */
 
@@ -260,6 +279,8 @@
 int br_receive_frame(struct sk_buff *skb);	/* 3.5 */
 int br_tx_frame(struct sk_buff *skb);
 int br_ioctl(unsigned int cmd, void *arg);
+
+int br_protocol_ok(unsigned short protocol);
 
 void free_fdb(struct fdb *);
 struct fdb *get_fdb(void);
diff -urN linux/net/bridge/br.c linux.bridge/net/bridge/br.c
--- linux/net/bridge/br.c	Thu Jul 18 22:24:05 1996
+++ linux.bridge/net/bridge/br.c	Mon Sep 16 21:30:06 1996
@@ -3,6 +3,10 @@
  *
  *	Originally by John Hayes (Network Plumbing).
  *	Minor hacks to get it to run with 1.3.x by Alan Cox <Alan.Cox@linux.org>
+ *	More hacks to be able to switch protocols on and off by Christoph Lameter
+ *	<clameter@debian.org>
+ *	Software and more Documentation for the bridge is available from ftp.debian.org
+ *	in the bridge package or at ftp.fuller.edu/Linux/bridge
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -79,6 +83,67 @@
 	0
 };
 
+/*
+ * Implementation of Protocol specific bridging
+ *
+ * The protocols to be bridged or not to be bridged are stored in a hashed array. This is the old type
+ * of unlinked hash array where one simply takes the next cell if the one the hash function points to
+ * is occupied.
+ */
+
+#define BR_PROTOCOL_HASH(x) (x % BR_MAX_PROTOCOLS)
+
+/* Checks if that protocol type is to be bridged */
+int br_protocol_ok(unsigned short protocol)
+{
+	unsigned x;
+	
+	/* See if protocol statistics are to be kept */
+	if (br_stats.flags & BR_PROT_STATS)
+	{ for(x=0;x<BR_MAX_PROT_STATS &&
+	     br_stats.prot_id[x]!=protocol && br_stats.prot_id[x];x++) ;
+	  if (x<BR_MAX_PROT_STATS)
+	  { br_stats.prot_id[x]=protocol;br_stats.prot_counter[x]++;
+	  }
+	}
+
+	for (x=BR_PROTOCOL_HASH(protocol); br_stats.protocols[x]!=0;) {
+		if (br_stats.protocols[x]==protocol) return !br_stats.policy;
+		x++;
+		if (x==BR_MAX_PROTOCOLS) x=0;
+	}
+	return br_stats.policy;
+}
+
+/* Add a protocol to be handled opposite to the standard policy of the bridge */
+
+int br_add_exempt_protocol(unsigned short p)
+{
+	unsigned x;
+	if (p == 0) return -EINVAL;
+	if (br_stats.exempt_protocols > BR_MAX_PROTOCOLS-2) return -EXFULL;
+	for (x=BR_PROTOCOL_HASH(p);br_stats.protocols[x]!=0;) {
+		if (br_stats.protocols[x]==p) return 0;	/* Attempt to add the protocol a second time */
+		x++;
+		if (x==BR_MAX_PROTOCOLS) x=0;
+	}
+	br_stats.protocols[x]=p;
+	br_stats.exempt_protocols++;
+	return 0;
+}
+
+/* Valid Policies are 0=No Protocols bridged 1=Bridge all protocols */
+int br_set_policy(int policy)
+{
+	if (policy>1) return -EINVAL;
+	br_stats.policy=policy;
+	/* Policy change means initializing the exempt table */
+	memset(br_stats.protocols,0,sizeof(br_stats.protocols));
+	br_stats.exempt_protocols = 0;
+	return 0;
+}
+
+
 /** Elements of Procedure (4.6) **/
 
 /*
@@ -611,6 +676,8 @@
 
 	register_netdevice_notifier(&br_dev_notifier);
 	br_stats.flags = 0; /*BR_UP | BR_DEBUG*/;	/* enable bridge */
+	br_stats.policy = BR_ACCEPT;			/* Enable bridge to accpet all protocols */
+	br_stats.exempt_protocols = 0;
 	/*start_hello_timer();*/
 }
 
@@ -1137,7 +1204,6 @@
 						/* happen in net_bh() in dev.c) */
 			}
 			/* ok, forward this frame... */
-			skb_device_lock(skb);
 			return(br_forward(skb, port));
 		default:
 			printk(KERN_DEBUG "br_receive_frame: port [%i] unknown state [%i]\n",
@@ -1454,7 +1520,7 @@
 		case SIOCSIFBR:
 			if (!suser())
 				return -EPERM;
-			err = verify_area(VERIFY_READ, arg, 
+			err = verify_area(VERIFY_READ , arg, 
 				sizeof(struct br_cf));
 			if(err)
 				return err;
@@ -1514,6 +1580,20 @@
 				case BRCMD_DISABLE_DEBUG:
 					br_stats.flags &= ~BR_DEBUG;
 					break;
+				case BRCMD_SET_POLICY:
+					return br_set_policy(bcf.arg1);
+				case BRCMD_EXEMPT_PROTOCOL:
+					return br_add_exempt_protocol(bcf.arg1);
+				case BRCMD_ENABLE_PROT_STATS:
+					br_stats.flags |= BR_PROT_STATS;
+					break;
+				case BRCMD_DISABLE_PROT_STATS:
+					br_stats.flags &= ~BR_PROT_STATS;
+					break;
+				case BRCMD_ZERO_PROT_STATS:
+					memset(&br_stats.prot_id,0,sizeof(br_stats.prot_id));
+					memset(&br_stats.prot_counter,0,sizeof(br_stats.prot_counter));
+					break;
 				default:
 					return -EINVAL;
 			}
@@ -1539,4 +1619,4 @@
 	}
 	return(0);
 }
-		
+
diff -urN linux/net/core/dev.c linux.bridge/net/core/dev.c
--- linux/net/core/dev.c	Thu Aug  1 05:43:04 1996
+++ linux.bridge/net/core/dev.c	Fri Sep 13 05:24:24 1996
@@ -603,10 +603,11 @@
 
 		/*
 		 *	If we are bridging then pass the frame up to the
-		 *	bridging code. If it is bridged then move on
+		 *	bridging code (if this protocol is to be bridged).
+		 *      If it is bridged then move on
 		 */
 		 
-		if (br_stats.flags & BR_UP)
+		if (br_stats.flags & BR_UP && br_protocol_ok(ntohs(skb->protocol)))
 		{
 			/*
 			 *	We pass the bridge a complete frame. This means
