}
 EXPORT_SYMBOL(xfrm4_tunnel_deregister);
 
+#define for_each_tunnel_rcu(head, handler)             \
+       for (handler = rcu_dereference(head);           \
+            handler != NULL;                           \
+            handler = rcu_dereference(handler->next))  \
+       
 static int tunnel4_rcv(struct sk_buff *skb)
 {
        struct xfrm_tunnel *handler;
        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
                goto drop;
 
-       for (handler = tunnel4_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel4_handlers, handler)
                if (!handler->handler(skb))
                        return 0;
 
        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
                goto drop;
 
-       for (handler = tunnel64_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel64_handlers, handler)
                if (!handler->handler(skb))
                        return 0;
 
 {
        struct xfrm_tunnel *handler;
 
-       for (handler = tunnel4_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel4_handlers, handler)
                if (!handler->err_handler(skb, info))
                        break;
 }
 {
        struct xfrm_tunnel *handler;
 
-       for (handler = tunnel64_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel64_handlers, handler)
                if (!handler->err_handler(skb, info))
                        break;
 }
 
 
 EXPORT_SYMBOL(xfrm6_tunnel_deregister);
 
+#define for_each_tunnel_rcu(head, handler)             \
+       for (handler = rcu_dereference(head);           \
+            handler != NULL;                           \
+            handler = rcu_dereference(handler->next))  \
+
 static int tunnel6_rcv(struct sk_buff *skb)
 {
        struct xfrm6_tunnel *handler;
        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
                goto drop;
 
-       for (handler = tunnel6_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel6_handlers, handler)
                if (!handler->handler(skb))
                        return 0;
 
        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
                goto drop;
 
-       for (handler = tunnel46_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel46_handlers, handler)
                if (!handler->handler(skb))
                        return 0;
 
 {
        struct xfrm6_tunnel *handler;
 
-       for (handler = tunnel6_handlers; handler; handler = handler->next)
+       for_each_tunnel_rcu(tunnel6_handlers, handler)
                if (!handler->err_handler(skb, opt, type, code, offset, info))
                        break;
 }