struct sock             *tcp_sk;
        struct sock             *igmp_sk;
        struct sock             *mc_autojoin_sk;
+
+       struct hlist_head       *inet6_addr_lst;
+       spinlock_t              addrconf_hash_lock;
+
 #ifdef CONFIG_IPV6_MROUTE
 #ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
        struct mr_table         *mrt6;
 
        int err = -ENOMEM;
        struct ipv6_devconf *all, *dflt;
 
+       spin_lock_init(&net->ipv6.addrconf_hash_lock);
+       net->ipv6.inet6_addr_lst = kcalloc(IN6_ADDR_HSIZE,
+                                          sizeof(struct hlist_head),
+                                          GFP_KERNEL);
+       if (!net->ipv6.inet6_addr_lst)
+               goto err_alloc_addr;
+
        all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
        if (!all)
                goto err_alloc_all;
 err_alloc_dflt:
        kfree(all);
 err_alloc_all:
+       kfree(net->ipv6.inet6_addr_lst);
+err_alloc_addr:
        return err;
 }
 
 static void __net_exit addrconf_exit_net(struct net *net)
 {
+       int i;
+
 #ifdef CONFIG_SYSCTL
        __addrconf_sysctl_unregister(net, net->ipv6.devconf_dflt,
                                     NETCONFA_IFINDEX_DEFAULT);
        net->ipv6.devconf_dflt = NULL;
        kfree(net->ipv6.devconf_all);
        net->ipv6.devconf_all = NULL;
+
+       /*
+        *      Check hash table, then free it.
+        */
+       for (i = 0; i < IN6_ADDR_HSIZE; i++)
+               WARN_ON_ONCE(!hlist_empty(&net->ipv6.inet6_addr_lst[i]));
+
+       kfree(net->ipv6.inet6_addr_lst);
+       net->ipv6.inet6_addr_lst = NULL;
 }
 
 static struct pernet_operations addrconf_ops = {