diff -urP linux/include/linux/firewall.h linux/include/linux/firewall.h --- linux/include/linux/firewall.h Sun Mar 25 11:31:05 2001 +++ linux/include/linux/firewall.h Tue Aug 27 16:29:41 2002 @@ -24,6 +24,10 @@ 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,7 +44,13 @@ 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 + +#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,6 +66,13 @@ return FW_ACCEPT; } -#endif -#endif -#endif +#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 -urP linux/include/linux/ip_fw.h linux/include/linux/ip_fw.h --- linux/include/linux/ip_fw.h Sun Mar 25 11:31:03 2001 +++ linux/include/linux/ip_fw.h Tue Aug 27 16:29:41 2002 @@ -101,6 +101,9 @@ #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 -urP linux/net/core/dev.c linux/net/core/dev.c --- linux/net/core/dev.c Mon May 20 19:32:35 2002 +++ linux/net/core/dev.c Tue Aug 27 16:29:41 2002 @@ -104,6 +104,10 @@ extern int cpc_init(void); extern void sync_ppp_init(void); +#ifdef CONFIG_FIREWALL +#include +#endif /* CONFIG_FIREWALL */ + NET_PROFILE_DEFINE(dev_queue_xmit) NET_PROFILE_DEFINE(net_bh) NET_PROFILE_DEFINE(net_bh_skb) @@ -820,12 +824,26 @@ */ if ((br_stats.flags & BR_UP) && br_call_bridge(skb, 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. */ - int offset; skb=skb_clone(skb, GFP_ATOMIC); if(skb==NULL) diff -urP linux/net/core/firewall.c linux/net/core/firewall.c --- linux/net/core/firewall.c Sun Mar 25 11:31:12 2001 +++ linux/net/core/firewall.c Tue Aug 27 16:29:41 2002 @@ -146,12 +146,34 @@ 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)) { int i; diff -urP linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c --- linux/net/ipv4/ip_fw.c Sun Mar 25 11:31:12 2001 +++ linux/net/ipv4/ip_fw.c Tue Aug 27 16:29:41 2002 @@ -270,6 +270,9 @@ #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, @@ -1286,6 +1289,9 @@ 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); @@ -1495,6 +1501,9 @@ 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"); @@ -1719,12 +1728,24 @@ 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 */ }; @@ -1753,6 +1774,9 @@ 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");