#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
 
 struct ip_ra_chain {
-       struct ip_ra_chain      *next;
+       struct ip_ra_chain __rcu *next;
        struct sock             *sk;
        union {
                void                    (*destructor)(struct sock *);
        struct rcu_head         rcu;
 };
 
-extern struct ip_ra_chain *ip_ra_chain;
+extern struct ip_ra_chain __rcu *ip_ra_chain;
 
 /* IP flags. */
 #define IP_CE          0x8000          /* Flag: "Congestion"           */
 
    but receiver should be enough clever f.e. to forward mtrace requests,
    sent to multicast group to reach destination designated router.
  */
-struct ip_ra_chain *ip_ra_chain;
+struct ip_ra_chain __rcu *ip_ra_chain;
 static DEFINE_SPINLOCK(ip_ra_lock);
 
 
 int ip_ra_control(struct sock *sk, unsigned char on,
                  void (*destructor)(struct sock *))
 {
-       struct ip_ra_chain *ra, *new_ra, **rap;
+       struct ip_ra_chain *ra, *new_ra;
+       struct ip_ra_chain __rcu **rap;
 
        if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW)
                return -EINVAL;
        new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
 
        spin_lock_bh(&ip_ra_lock);
-       for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) {
+       for (rap = &ip_ra_chain;
+            (ra = rcu_dereference_protected(*rap,
+                       lockdep_is_held(&ip_ra_lock))) != NULL;
+            rap = &ra->next) {
                if (ra->sk == sk) {
                        if (on) {
                                spin_unlock_bh(&ip_ra_lock);