diff -cr linux-2.2.5.org/include/linux/firewall.h linux/include/linux/firewall.h
*** linux-2.2.5.org/include/linux/firewall.h	Tue Apr 20 03:41:58 1999
--- linux/include/linux/firewall.h	Tue May 25 10:14:00 1999
***************
*** 24,29 ****
--- 24,33 ----
  			struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
  	int (*fw_output)(struct firewall_ops *this, int pf, 
  			struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
+ #ifdef CONFIG_BRIDGE
+ 	int (*fw_bridgein)(struct firewall_ops *this, int pf, 
+ 			struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
+ #endif
  	/* Data falling in the second 486 cache line isn't used directly
  	   during a firewall call and scan, only by insert/delete and other
  	   unusual cases
***************
*** 40,46 ****
  extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
  extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
  extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
! #else
  extern __inline__ int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **skb)
  {
  	return FW_ACCEPT;
--- 44,56 ----
  extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
  extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
  extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
! 
! #ifdef CONFIG_BRIDGE
! extern int call_bridgein_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb);
! #endif	/* CONFIG_BRIDGE */
! 
! #else	/* CONFIG_FIREWALL */
! 
  extern __inline__ int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **skb)
  {
  	return FW_ACCEPT;
***************
*** 56,61 ****
  	return FW_ACCEPT;
  }
  
! #endif
! #endif
! #endif
--- 66,78 ----
  	return FW_ACCEPT;
  }
  
! #ifdef CONFIG_BRIDGE
! extern __inline__ int call_bridgein_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **skb)
! {
! 	return FW_ACCEPT;
! }
! #endif /* CONFIG_BRIDGE */
! 
! #endif	/* CONFIG_FIREWALL */
! #endif   /* __KERNEL__ */
! #endif   /* __LINUX_FIREWALL_H */
diff -cr linux-2.2.5.org/include/linux/ip_fw.h linux/include/linux/ip_fw.h
*** linux-2.2.5.org/include/linux/ip_fw.h	Tue Apr 20 03:42:16 1999
--- linux/include/linux/ip_fw.h	Tue May 25 10:09:44 1999
***************
*** 101,106 ****
--- 101,109 ----
  #define IP_FW_LABEL_FORWARD	"forward"
  #define IP_FW_LABEL_INPUT	"input"
  #define IP_FW_LABEL_OUTPUT	"output"
+ #ifdef CONFIG_BRIDGE
+ #define IP_FW_LABEL_BRIDGEIN	"bridgein"
+ #endif
  
  /* Special targets */
  #define IP_FW_LABEL_MASQUERADE  "MASQ"
diff -cr linux-2.2.5.org/net/core/dev.c linux/net/core/dev.c
*** linux-2.2.5.org/net/core/dev.c	Thu Mar 25 18:23:34 1999
--- linux/net/core/dev.c	Tue May 25 10:12:53 1999
***************
*** 94,99 ****
--- 94,103 ----
  extern int plip_init(void);
  #endif
  
+ #ifdef   CONFIG_FIREWALL
+ #include <linux/firewall.h>
+ #endif /* CONFIG_FIREWALL */
+ 
  NET_PROFILE_DEFINE(dev_queue_xmit)
  NET_PROFILE_DEFINE(net_bh)
  NET_PROFILE_DEFINE(net_bh_skb)
***************
*** 797,808 ****
  {
  	if (br_stats.flags & BR_UP && br_protocol_ok(ntohs(type)))
  	{
  		/*
  		 *	We pass the bridge a complete frame. This means
  		 *	recovering the MAC header first.
  		 */
  		
- 		int offset;
  
  		skb=skb_clone(skb, GFP_ATOMIC);
  		if(skb==NULL)		
--- 801,826 ----
  {
  	if (br_stats.flags & BR_UP && br_protocol_ok(ntohs(type)))
  	{
+ 		int offset;
+ 
+ #ifdef   CONFIG_FIREWALL
+ 		if(type==__constant_htons(ETH_P_IP))
+ 		{
+    		int fwres;
+    		u16 rport;
+ 
+ 			/* call the bridge input filter function */
+ 			fwres = call_bridgein_firewall(PF_INET, skb->dev, skb->nh.iph, &rport, &skb);
+ 			if (fwres < FW_ACCEPT && fwres != FW_REJECT)
+ 				return;
+ 		}
+ #endif /* CONFIG_FIREWALL */
+ 
  		/*
  		 *	We pass the bridge a complete frame. This means
  		 *	recovering the MAC header first.
  		 */
  		
  
  		skb=skb_clone(skb, GFP_ATOMIC);
  		if(skb==NULL)		
diff -cr linux-2.2.5.org/net/core/firewall.c linux/net/core/firewall.c
*** linux-2.2.5.org/net/core/firewall.c	Tue Dec 29 20:21:49 1998
--- linux/net/core/firewall.c	Tue May 25 09:40:25 1999
***************
*** 146,156 ****
--- 146,178 ----
  	return firewall_policy[pf];
  }
  
+ #ifdef CONFIG_BRIDGE
+ int call_bridgein_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **skb)
+ {
+ 	struct firewall_ops *fw=firewall_chain[pf];
+ 
+ 	while(fw!=NULL)
+ 	{
+ 		int rc=fw->fw_bridgein(fw,pf,dev,phdr,arg,skb);
+ 		if(rc!=FW_SKIP)
+ 			return rc;
+ 		fw=fw->next;
+ 	}
+ 	/* alan, is this right? */
+ 	return firewall_policy[pf];
+ }
+ #endif
+ 
  EXPORT_SYMBOL(register_firewall);
  EXPORT_SYMBOL(unregister_firewall);
  EXPORT_SYMBOL(call_in_firewall);
  EXPORT_SYMBOL(call_out_firewall);
  EXPORT_SYMBOL(call_fw_firewall);
+ 
+ #ifdef CONFIG_BRIDGE
+ EXPORT_SYMBOL(call_bridgein_firewall);
+ #endif /* CONFIG_BRIDGE */
+ 
  
  __initfunc(void fwchain_init(void))
  {
diff -cr linux-2.2.5.org/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
*** linux-2.2.5.org/net/ipv4/ip_fw.c	Tue Apr 20 03:10:50 1999
--- linux/net/ipv4/ip_fw.c	Tue May 25 09:52:22 1999
***************
*** 259,264 ****
--- 259,267 ----
  #define IP_FW_INPUT_CHAIN ip_fw_chains
  #define IP_FW_FORWARD_CHAIN (ip_fw_chains->next)
  #define IP_FW_OUTPUT_CHAIN (ip_fw_chains->next->next)
+ #ifdef CONFIG_BRIDGE
+ #define IP_FW_BRIDGEIN_CHAIN (ip_fw_chains->next->next->next)
+ #endif
  
  /* Returns 1 if the port is matched by the range, 0 otherwise */
  extern inline int port_match(__u16 min, __u16 max, __u16 port,
***************
*** 1249,1254 ****
--- 1252,1260 ----
  			return NULL;
  		} else if (fwkern->branch == IP_FW_INPUT_CHAIN 
  			   || fwkern->branch == IP_FW_FORWARD_CHAIN
+ #ifdef CONFIG_BRIDGE
+ 			   || fwkern->branch == IP_FW_BRIDGEIN_CHAIN
+ #endif
  			   || fwkern->branch == IP_FW_OUTPUT_CHAIN) {
  			duprintf("convert_ipfw: Can't branch to builtin chain `%s'.\n",
  				 fwuser->label);
***************
*** 1456,1461 ****
--- 1462,1470 ----
  			ret = ENOENT;
  		else if (chain != IP_FW_INPUT_CHAIN
  			 && chain != IP_FW_FORWARD_CHAIN
+ #ifdef CONFIG_BRIDGE
+ 			 && chain != IP_FW_BRIDGEIN_CHAIN
+ #endif
  			 && chain != IP_FW_OUTPUT_CHAIN) {
  			duprintf("change_policy: can't change policy on user" 
  				 " defined chain.\n");
***************
*** 1676,1687 ****
--- 1685,1708 ----
  			   arg, IP_FW_FORWARD_CHAIN, *pskb, SLOT_NUMBER(), 0);
  }
  
+ #ifdef CONFIG_BRIDGE
+ int ipfw_bridgein_check(struct firewall_ops *this, int pf, struct device *dev, 
+ 		       void *phdr, void *arg, struct sk_buff **pskb)
+ {
+ 	return ip_fw_check(phdr, dev->name,
+ 			   arg, IP_FW_BRIDGEIN_CHAIN, *pskb, SLOT_NUMBER(), 0);
+ }
+ #endif
+ 
  struct firewall_ops ipfw_ops=
  {
  	NULL,
  	ipfw_forward_check,
  	ipfw_input_check,
  	ipfw_output_check,
+ #ifdef CONFIG_BRIDGE
+ 	ipfw_bridgein_check,
+ #endif
  	PF_INET,
  	0	/* We don't even allow a fall through so we are last */
  };
***************
*** 1710,1715 ****
--- 1731,1739 ----
  	IP_FW_INPUT_CHAIN = ip_init_chain(IP_FW_LABEL_INPUT, 1, FW_ACCEPT);
  	IP_FW_FORWARD_CHAIN = ip_init_chain(IP_FW_LABEL_FORWARD, 1, FW_ACCEPT);
  	IP_FW_OUTPUT_CHAIN = ip_init_chain(IP_FW_LABEL_OUTPUT, 1, FW_ACCEPT);
+ #ifdef CONFIG_BRIDGE
+ 	IP_FW_BRIDGEIN_CHAIN = ip_init_chain(IP_FW_LABEL_BRIDGEIN, 1, FW_ACCEPT);
+ #endif
  
  	if(register_firewall(PF_INET,&ipfw_ops)<0)
  		panic("Unable to register IP firewall.\n");
