| 1 | --- a/net/bridge/br_forward.c |
| 2 | +++ b/net/bridge/br_forward.c |
| 3 | @@ -55,7 +55,7 @@ int br_dev_queue_push_xmit(struct sk_buf |
| 4 | |
| 5 | int br_forward_finish(struct sk_buff *skb) |
| 6 | { |
| 7 | - return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, |
| 8 | + return BR_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, |
| 9 | br_dev_queue_push_xmit); |
| 10 | |
| 11 | } |
| 12 | @@ -74,7 +74,7 @@ static void __br_deliver(const struct ne |
| 13 | return; |
| 14 | } |
| 15 | |
| 16 | - NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 17 | + BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 18 | br_forward_finish); |
| 19 | } |
| 20 | |
| 21 | @@ -91,7 +91,7 @@ static void __br_forward(const struct ne |
| 22 | skb->dev = to->dev; |
| 23 | skb_forward_csum(skb); |
| 24 | |
| 25 | - NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, |
| 26 | + BR_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, |
| 27 | br_forward_finish); |
| 28 | } |
| 29 | |
| 30 | --- a/net/bridge/br_input.c |
| 31 | +++ b/net/bridge/br_input.c |
| 32 | @@ -40,7 +40,7 @@ static int br_pass_frame_up(struct sk_bu |
| 33 | indev = skb->dev; |
| 34 | skb->dev = brdev; |
| 35 | |
| 36 | - return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, |
| 37 | + return BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, |
| 38 | netif_receive_skb); |
| 39 | } |
| 40 | |
| 41 | @@ -199,7 +199,7 @@ rx_handler_result_t br_handle_frame(stru |
| 42 | } |
| 43 | |
| 44 | /* Deliver packet to local host only */ |
| 45 | - if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, |
| 46 | + if (BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, |
| 47 | NULL, br_handle_local_finish)) { |
| 48 | return RX_HANDLER_CONSUMED; /* consumed by filter */ |
| 49 | } else { |
| 50 | @@ -224,7 +224,7 @@ forward: |
| 51 | if (!compare_ether_addr(p->br->dev->dev_addr, dest)) |
| 52 | skb->pkt_type = PACKET_HOST; |
| 53 | |
| 54 | - NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, |
| 55 | + BR_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, |
| 56 | br_handle_frame_finish); |
| 57 | break; |
| 58 | default: |
| 59 | --- a/net/bridge/br_multicast.c |
| 60 | +++ b/net/bridge/br_multicast.c |
| 61 | @@ -753,7 +753,7 @@ static void __br_multicast_send_query(st |
| 62 | if (port) { |
| 63 | __skb_push(skb, sizeof(struct ethhdr)); |
| 64 | skb->dev = port->dev; |
| 65 | - NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 66 | + BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 67 | dev_queue_xmit); |
| 68 | } else |
| 69 | netif_rx(skb); |
| 70 | --- a/net/bridge/br_netfilter.c |
| 71 | +++ b/net/bridge/br_netfilter.c |
| 72 | @@ -71,6 +71,15 @@ static int brnf_filter_pppoe_tagged __re |
| 73 | #define IS_ARP(skb) \ |
| 74 | (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_ARP)) |
| 75 | |
| 76 | +int brnf_call_ebtables __read_mostly = 0; |
| 77 | +EXPORT_SYMBOL_GPL(brnf_call_ebtables); |
| 78 | + |
| 79 | +bool br_netfilter_run_hooks(void) |
| 80 | +{ |
| 81 | + return brnf_call_iptables | brnf_call_ip6tables | brnf_call_arptables | |
| 82 | + brnf_call_ebtables; |
| 83 | +} |
| 84 | + |
| 85 | static inline __be16 vlan_proto(const struct sk_buff *skb) |
| 86 | { |
| 87 | if (vlan_tx_tag_present(skb)) |
| 88 | --- a/net/bridge/br_private.h |
| 89 | +++ b/net/bridge/br_private.h |
| 90 | @@ -486,15 +486,29 @@ static inline bool br_multicast_is_route |
| 91 | |
| 92 | /* br_netfilter.c */ |
| 93 | #ifdef CONFIG_BRIDGE_NETFILTER |
| 94 | +extern int brnf_call_ebtables; |
| 95 | extern int br_netfilter_init(void); |
| 96 | extern void br_netfilter_fini(void); |
| 97 | extern void br_netfilter_rtable_init(struct net_bridge *); |
| 98 | +extern bool br_netfilter_run_hooks(void); |
| 99 | #else |
| 100 | #define br_netfilter_init() (0) |
| 101 | #define br_netfilter_fini() do { } while(0) |
| 102 | #define br_netfilter_rtable_init(x) |
| 103 | +#define br_netfilter_run_hooks() false |
| 104 | #endif |
| 105 | |
| 106 | +static inline int |
| 107 | +BR_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb, |
| 108 | + struct net_device *in, struct net_device *out, |
| 109 | + int (*okfn)(struct sk_buff *)) |
| 110 | +{ |
| 111 | + if (!br_netfilter_run_hooks()) |
| 112 | + return okfn(skb); |
| 113 | + |
| 114 | + return NF_HOOK(pf, hook, skb, in, out, okfn); |
| 115 | +} |
| 116 | + |
| 117 | /* br_stp.c */ |
| 118 | extern void br_log_state(const struct net_bridge_port *p); |
| 119 | extern struct net_bridge_port *br_get_port(struct net_bridge *br, |
| 120 | --- a/net/bridge/br_stp_bpdu.c |
| 121 | +++ b/net/bridge/br_stp_bpdu.c |
| 122 | @@ -52,7 +52,7 @@ static void br_send_bpdu(struct net_brid |
| 123 | |
| 124 | skb_reset_mac_header(skb); |
| 125 | |
| 126 | - NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 127 | + BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 128 | dev_queue_xmit); |
| 129 | } |
| 130 | |
| 131 | --- a/net/bridge/netfilter/ebtables.c |
| 132 | +++ b/net/bridge/netfilter/ebtables.c |
| 133 | @@ -2403,11 +2403,13 @@ static int __init ebtables_init(void) |
| 134 | } |
| 135 | |
| 136 | printk(KERN_INFO "Ebtables v2.0 registered\n"); |
| 137 | + brnf_call_ebtables = 1; |
| 138 | return 0; |
| 139 | } |
| 140 | |
| 141 | static void __exit ebtables_fini(void) |
| 142 | { |
| 143 | + brnf_call_ebtables = 0; |
| 144 | nf_unregister_sockopt(&ebt_sockopts); |
| 145 | xt_unregister_target(&ebt_standard_target); |
| 146 | printk(KERN_INFO "Ebtables v2.0 unregistered\n"); |
| 147 | |