#include <linux/netdevice.h>
 
 extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
-extern int (*br_should_route_hook)(struct sk_buff *skb);
+
+typedef int (*br_should_route_hook_t)(struct sk_buff *skb);
+extern br_should_route_hook_t __rcu *br_should_route_hook;
 
 #endif
 
 
 
 #include "br_private.h"
 
-int (*br_should_route_hook)(struct sk_buff *skb);
-
 static const struct stp_proto br_stp_proto = {
        .rcv    = br_stp_rcv,
 };
        br_fdb_fini();
 }
 
-EXPORT_SYMBOL(br_should_route_hook);
-
 module_init(br_init)
 module_exit(br_deinit)
 MODULE_LICENSE("GPL");
 
 /* Bridge group multicast address 802.1d (pg 51). */
 const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
 
+/* Hook for brouter */
+br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
+EXPORT_SYMBOL(br_should_route_hook);
+
 static int br_pass_frame_up(struct sk_buff *skb)
 {
        struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
 {
        struct net_bridge_port *p;
        const unsigned char *dest = eth_hdr(skb)->h_dest;
-       int (*rhook)(struct sk_buff *skb);
+       br_should_route_hook_t *rhook;
 
        if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
                return skb;
        switch (p->state) {
        case BR_STATE_FORWARDING:
                rhook = rcu_dereference(br_should_route_hook);
-               if (rhook != NULL) {
-                       if (rhook(skb))
+               if (rhook) {
+                       if ((*rhook)(skb))
                                return skb;
                        dest = eth_hdr(skb)->h_dest;
                }
 
        if (ret < 0)
                return ret;
        /* see br_input.c */
-       rcu_assign_pointer(br_should_route_hook, ebt_broute);
+       rcu_assign_pointer(br_should_route_hook,
+                          (br_should_route_hook_t *)ebt_broute);
        return 0;
 }