From 6f8b023b69ba53cc90b4ab603ef8d5539a381888 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 29 Mar 2012 14:15:54 +0000 Subject: [PATCH] kernel: restore ebtables functionality by running netfilter hooks when the ebtables module is loaded git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31141 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../644-bridge_optimize_netfilter_hooks.patch | 30 +++- .../644-bridge_optimize_netfilter_hooks.patch | 166 ++++++++++-------- 2 files changed, 122 insertions(+), 74 deletions(-) diff --git a/target/linux/generic/patches-3.2/644-bridge_optimize_netfilter_hooks.patch b/target/linux/generic/patches-3.2/644-bridge_optimize_netfilter_hooks.patch index 91139854bb..6c3c3e5c60 100644 --- a/target/linux/generic/patches-3.2/644-bridge_optimize_netfilter_hooks.patch +++ b/target/linux/generic/patches-3.2/644-bridge_optimize_netfilter_hooks.patch @@ -1,12 +1,16 @@ --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c -@@ -62,6 +62,11 @@ static int brnf_filter_pppoe_tagged __re +@@ -62,6 +62,15 @@ static int brnf_filter_pppoe_tagged __re #define brnf_filter_pppoe_tagged 0 #endif ++int brnf_call_ebtables __read_mostly = 0; ++EXPORT_SYMBOL_GPL(brnf_call_ebtables); ++ +bool br_netfilter_run_hooks(void) +{ -+ return brnf_call_iptables | brnf_call_ip6tables | brnf_call_arptables; ++ return brnf_call_iptables | brnf_call_ip6tables | brnf_call_arptables | ++ brnf_call_ebtables; +} + static inline __be16 vlan_proto(const struct sk_buff *skb) @@ -14,7 +18,11 @@ if (vlan_tx_tag_present(skb)) --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h -@@ -491,12 +491,25 @@ static inline bool br_multicast_is_route +@@ -488,15 +488,29 @@ static inline bool br_multicast_is_route + + /* br_netfilter.c */ + #ifdef CONFIG_BRIDGE_NETFILTER ++extern int brnf_call_ebtables; extern int br_netfilter_init(void); extern void br_netfilter_fini(void); extern void br_netfilter_rtable_init(struct net_bridge *); @@ -120,3 +128,19 @@ dev_queue_xmit); } +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -2399,11 +2399,13 @@ static int __init ebtables_init(void) + } + + printk(KERN_INFO "Ebtables v2.0 registered\n"); ++ brnf_call_ebtables = 1; + return 0; + } + + static void __exit ebtables_fini(void) + { ++ brnf_call_ebtables = 0; + nf_unregister_sockopt(&ebt_sockopts); + xt_unregister_target(&ebt_standard_target); + printk(KERN_INFO "Ebtables v2.0 unregistered\n"); diff --git a/target/linux/generic/patches-3.3/644-bridge_optimize_netfilter_hooks.patch b/target/linux/generic/patches-3.3/644-bridge_optimize_netfilter_hooks.patch index d2fdd614c3..3b02c5cf94 100644 --- a/target/linux/generic/patches-3.3/644-bridge_optimize_netfilter_hooks.patch +++ b/target/linux/generic/patches-3.3/644-bridge_optimize_netfilter_hooks.patch @@ -1,74 +1,3 @@ ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -40,7 +40,7 @@ static int br_pass_frame_up(struct sk_bu - indev = skb->dev; - skb->dev = brdev; - -- return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, -+ return BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, - netif_receive_skb); - } - -@@ -199,7 +199,7 @@ rx_handler_result_t br_handle_frame(stru - } - - /* Deliver packet to local host only */ -- if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, -+ if (BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, - NULL, br_handle_local_finish)) { - return RX_HANDLER_CONSUMED; /* consumed by filter */ - } else { -@@ -224,7 +224,7 @@ forward: - if (!compare_ether_addr(p->br->dev->dev_addr, dest)) - skb->pkt_type = PACKET_HOST; - -- NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, -+ BR_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, - br_handle_frame_finish); - break; - default: ---- a/net/bridge/br_netfilter.c -+++ b/net/bridge/br_netfilter.c -@@ -71,6 +71,11 @@ static int brnf_filter_pppoe_tagged __re - #define IS_ARP(skb) \ - (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_ARP)) - -+bool br_netfilter_run_hooks(void) -+{ -+ return brnf_call_iptables | brnf_call_ip6tables | brnf_call_arptables; -+} -+ - static inline __be16 vlan_proto(const struct sk_buff *skb) - { - if (vlan_tx_tag_present(skb)) ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -493,12 +493,25 @@ static inline bool br_multicast_is_route - extern int br_netfilter_init(void); - extern void br_netfilter_fini(void); - extern void br_netfilter_rtable_init(struct net_bridge *); -+extern bool br_netfilter_run_hooks(void); - #else - #define br_netfilter_init() (0) - #define br_netfilter_fini() do { } while(0) - #define br_netfilter_rtable_init(x) -+#define br_netfilter_run_hooks() false - #endif - -+static inline int -+BR_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb, -+ struct net_device *in, struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ if (!br_netfilter_run_hooks()) -+ return okfn(skb); -+ -+ return NF_HOOK(pf, hook, skb, in, out, okfn); -+} -+ - /* br_stp.c */ - extern void br_log_state(const struct net_bridge_port *p); - extern struct net_bridge_port *br_get_port(struct net_bridge *br, --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -55,7 +55,7 @@ int br_dev_queue_push_xmit(struct sk_buf @@ -98,6 +27,35 @@ br_forward_finish); } +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -40,7 +40,7 @@ static int br_pass_frame_up(struct sk_bu + indev = skb->dev; + skb->dev = brdev; + +- return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, ++ return BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, + netif_receive_skb); + } + +@@ -199,7 +199,7 @@ rx_handler_result_t br_handle_frame(stru + } + + /* Deliver packet to local host only */ +- if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, ++ if (BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, + NULL, br_handle_local_finish)) { + return RX_HANDLER_CONSUMED; /* consumed by filter */ + } else { +@@ -224,7 +224,7 @@ forward: + if (!compare_ether_addr(p->br->dev->dev_addr, dest)) + skb->pkt_type = PACKET_HOST; + +- NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, ++ BR_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, + br_handle_frame_finish); + break; + default: --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -827,7 +827,7 @@ static void __br_multicast_send_query(st @@ -109,6 +67,56 @@ dev_queue_xmit); } else netif_rx(skb); +--- a/net/bridge/br_netfilter.c ++++ b/net/bridge/br_netfilter.c +@@ -71,6 +71,15 @@ static int brnf_filter_pppoe_tagged __re + #define IS_ARP(skb) \ + (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_ARP)) + ++int brnf_call_ebtables __read_mostly = 0; ++EXPORT_SYMBOL_GPL(brnf_call_ebtables); ++ ++bool br_netfilter_run_hooks(void) ++{ ++ return brnf_call_iptables | brnf_call_ip6tables | brnf_call_arptables | ++ brnf_call_ebtables; ++} ++ + static inline __be16 vlan_proto(const struct sk_buff *skb) + { + if (vlan_tx_tag_present(skb)) +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -490,15 +490,29 @@ static inline bool br_multicast_is_route + + /* br_netfilter.c */ + #ifdef CONFIG_BRIDGE_NETFILTER ++extern int brnf_call_ebtables; + extern int br_netfilter_init(void); + extern void br_netfilter_fini(void); + extern void br_netfilter_rtable_init(struct net_bridge *); ++extern bool br_netfilter_run_hooks(void); + #else + #define br_netfilter_init() (0) + #define br_netfilter_fini() do { } while(0) + #define br_netfilter_rtable_init(x) ++#define br_netfilter_run_hooks() false + #endif + ++static inline int ++BR_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb, ++ struct net_device *in, struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ if (!br_netfilter_run_hooks()) ++ return okfn(skb); ++ ++ return NF_HOOK(pf, hook, skb, in, out, okfn); ++} ++ + /* br_stp.c */ + extern void br_log_state(const struct net_bridge_port *p); + extern struct net_bridge_port *br_get_port(struct net_bridge *br, --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c @@ -52,7 +52,7 @@ static void br_send_bpdu(struct net_brid @@ -120,3 +128,19 @@ dev_queue_xmit); } +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -2403,11 +2403,13 @@ static int __init ebtables_init(void) + } + + printk(KERN_INFO "Ebtables v2.0 registered\n"); ++ brnf_call_ebtables = 1; + return 0; + } + + static void __exit ebtables_fini(void) + { ++ brnf_call_ebtables = 0; + nf_unregister_sockopt(&ebt_sockopts); + xt_unregister_target(&ebt_standard_target); + printk(KERN_INFO "Ebtables v2.0 unregistered\n");