@@ -126,7 +126,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev);
126126/*
127127 * Configured unicast address hash table
128128 */
129- static struct inet6_ifaddr * inet6_addr_lst [IN6_ADDR_HSIZE ];
129+ static struct hlist_head inet6_addr_lst [IN6_ADDR_HSIZE ];
130130static DEFINE_RWLOCK (addrconf_hash_lock );
131131
132132static void addrconf_verify (unsigned long );
@@ -528,7 +528,7 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
528528void inet6_ifa_finish_destroy (struct inet6_ifaddr * ifp )
529529{
530530 WARN_ON (ifp -> if_next != NULL );
531- WARN_ON (ifp -> lst_next != NULL );
531+ WARN_ON (! hlist_unhashed ( & ifp -> addr_lst ) );
532532
533533#ifdef NET_REFCNT_DEBUG
534534 printk (KERN_DEBUG "inet6_ifa_finish_destroy\n" );
@@ -643,6 +643,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
643643
644644 spin_lock_init (& ifa -> lock );
645645 init_timer (& ifa -> timer );
646+ INIT_HLIST_NODE (& ifa -> addr_lst );
646647 ifa -> timer .data = (unsigned long ) ifa ;
647648 ifa -> scope = scope ;
648649 ifa -> prefix_len = pfxlen ;
@@ -669,8 +670,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
669670 /* Add to big hash table */
670671 hash = ipv6_addr_hash (addr );
671672
672- ifa -> lst_next = inet6_addr_lst [hash ];
673- inet6_addr_lst [hash ] = ifa ;
673+ hlist_add_head (& ifa -> addr_lst , & inet6_addr_lst [hash ]);
674674 in6_ifa_hold (ifa );
675675 write_unlock (& addrconf_hash_lock );
676676
@@ -718,15 +718,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
718718 ifp -> dead = 1 ;
719719
720720 write_lock_bh (& addrconf_hash_lock );
721- for (ifap = & inet6_addr_lst [hash ]; (ifa = * ifap ) != NULL ;
722- ifap = & ifa -> lst_next ) {
723- if (ifa == ifp ) {
724- * ifap = ifa -> lst_next ;
725- __in6_ifa_put (ifp );
726- ifa -> lst_next = NULL ;
727- break ;
728- }
729- }
721+ hlist_del_init (& ifp -> addr_lst );
722+ __in6_ifa_put (ifp );
730723 write_unlock_bh (& addrconf_hash_lock );
731724
732725 write_lock_bh (& idev -> lock );
@@ -1277,11 +1270,12 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
12771270int ipv6_chk_addr (struct net * net , struct in6_addr * addr ,
12781271 struct net_device * dev , int strict )
12791272{
1280- struct inet6_ifaddr * ifp ;
1273+ struct inet6_ifaddr * ifp = NULL ;
1274+ struct hlist_node * node ;
12811275 u8 hash = ipv6_addr_hash (addr );
12821276
12831277 read_lock_bh (& addrconf_hash_lock );
1284- for (ifp = inet6_addr_lst [hash ]; ifp ; ifp = ifp -> lst_next ) {
1278+ hlist_for_each_entry (ifp , node , & inet6_addr_lst [hash ], addr_lst ) {
12851279 if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
12861280 continue ;
12871281 if (ipv6_addr_equal (& ifp -> addr , addr ) &&
@@ -1300,10 +1294,11 @@ static
13001294int ipv6_chk_same_addr (struct net * net , const struct in6_addr * addr ,
13011295 struct net_device * dev )
13021296{
1303- struct inet6_ifaddr * ifp ;
1297+ struct inet6_ifaddr * ifp ;
1298+ struct hlist_node * node ;
13041299 u8 hash = ipv6_addr_hash (addr );
13051300
1306- for (ifp = inet6_addr_lst [hash ]; ifp ; ifp = ifp -> lst_next ) {
1301+ hlist_for_each_entry (ifp , node , & inet6_addr_lst [hash ], addr_lst ) {
13071302 if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
13081303 continue ;
13091304 if (ipv6_addr_equal (& ifp -> addr , addr )) {
@@ -1342,11 +1337,12 @@ EXPORT_SYMBOL(ipv6_chk_prefix);
13421337struct inet6_ifaddr * ipv6_get_ifaddr (struct net * net , const struct in6_addr * addr ,
13431338 struct net_device * dev , int strict )
13441339{
1345- struct inet6_ifaddr * ifp ;
1340+ struct inet6_ifaddr * ifp = NULL ;
1341+ struct hlist_node * node ;
13461342 u8 hash = ipv6_addr_hash (addr );
13471343
13481344 read_lock_bh (& addrconf_hash_lock );
1349- for (ifp = inet6_addr_lst [hash ]; ifp ; ifp = ifp -> lst_next ) {
1345+ hlist_for_each_entry (ifp , node , & inet6_addr_lst [hash ], addr_lst ) {
13501346 if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
13511347 continue ;
13521348 if (ipv6_addr_equal (& ifp -> addr , addr )) {
@@ -2612,7 +2608,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
26122608 struct inet6_dev * idev ;
26132609 struct inet6_ifaddr * ifa , * keep_list , * * bifa ;
26142610 struct net * net = dev_net (dev );
2615- int i ;
26162611
26172612 ASSERT_RTNL ();
26182613
@@ -2637,25 +2632,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
26372632
26382633 }
26392634
2640- /* Step 2: clear hash table */
2641- for (i = 0 ; i < IN6_ADDR_HSIZE ; i ++ ) {
2642- bifa = & inet6_addr_lst [i ];
2643-
2644- write_lock_bh (& addrconf_hash_lock );
2645- while ((ifa = * bifa ) != NULL ) {
2646- if (ifa -> idev == idev &&
2647- (how || !(ifa -> flags & IFA_F_PERMANENT ) ||
2648- ipv6_addr_type (& ifa -> addr ) & IPV6_ADDR_LINKLOCAL )) {
2649- * bifa = ifa -> lst_next ;
2650- ifa -> lst_next = NULL ;
2651- __in6_ifa_put (ifa );
2652- continue ;
2653- }
2654- bifa = & ifa -> lst_next ;
2655- }
2656- write_unlock_bh (& addrconf_hash_lock );
2657- }
2658-
26592635 write_lock_bh (& idev -> lock );
26602636
26612637 /* Step 3: clear flags for stateless addrconf */
@@ -2721,6 +2697,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
27212697 }
27222698 write_unlock_bh (& idev -> lock );
27232699
2700+ /* clear hash table */
2701+ write_lock_bh (& addrconf_hash_lock );
2702+ hlist_del_init (& ifa -> addr_lst );
2703+ __in6_ifa_put (ifa );
2704+ write_unlock_bh (& addrconf_hash_lock );
2705+
27242706 __ipv6_ifa_notify (RTM_DELADDR , ifa );
27252707 atomic_notifier_call_chain (& inet6addr_chain , NETDEV_DOWN , ifa );
27262708 in6_ifa_put (ifa );
@@ -2963,36 +2945,37 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
29632945 struct net * net = seq_file_net (seq );
29642946
29652947 for (state -> bucket = 0 ; state -> bucket < IN6_ADDR_HSIZE ; ++ state -> bucket ) {
2966- ifa = inet6_addr_lst [ state -> bucket ] ;
2967-
2968- while ( ifa && ! net_eq ( dev_net ( ifa -> idev -> dev ), net ))
2969- ifa = ifa -> lst_next ;
2970- if ( ifa )
2971- break ;
2948+ struct hlist_node * n ;
2949+ hlist_for_each_entry ( ifa , n ,
2950+ & inet6_addr_lst [ state -> bucket ], addr_lst ) {
2951+ if ( net_eq ( dev_net ( ifa -> idev -> dev ), net ))
2952+ return ifa ;
2953+ }
29722954 }
2973- return ifa ;
2955+ return NULL ;
29742956}
29752957
2976- static struct inet6_ifaddr * if6_get_next (struct seq_file * seq , struct inet6_ifaddr * ifa )
2958+ static struct inet6_ifaddr * if6_get_next (struct seq_file * seq ,
2959+ struct inet6_ifaddr * ifa )
29772960{
29782961 struct if6_iter_state * state = seq -> private ;
29792962 struct net * net = seq_file_net (seq );
2963+ struct hlist_node * n = & ifa -> addr_lst ;
29802964
2981- ifa = ifa -> lst_next ;
2982- try_again :
2983- if (ifa ) {
2984- if (!net_eq (dev_net (ifa -> idev -> dev ), net )) {
2985- ifa = ifa -> lst_next ;
2986- goto try_again ;
2987- }
2965+ hlist_for_each_entry_continue (ifa , n , addr_lst ) {
2966+ if (net_eq (dev_net (ifa -> idev -> dev ), net ))
2967+ return ifa ;
29882968 }
29892969
2990- if (!ifa && ++ state -> bucket < IN6_ADDR_HSIZE ) {
2991- ifa = inet6_addr_lst [state -> bucket ];
2992- goto try_again ;
2970+ while (++ state -> bucket < IN6_ADDR_HSIZE ) {
2971+ hlist_for_each_entry (ifa , n ,
2972+ & inet6_addr_lst [state -> bucket ], addr_lst ) {
2973+ if (net_eq (dev_net (ifa -> idev -> dev ), net ))
2974+ return ifa ;
2975+ }
29932976 }
29942977
2995- return ifa ;
2978+ return NULL ;
29962979}
29972980
29982981static struct inet6_ifaddr * if6_get_idx (struct seq_file * seq , loff_t pos )
@@ -3094,10 +3077,12 @@ void if6_proc_exit(void)
30943077int ipv6_chk_home_addr (struct net * net , struct in6_addr * addr )
30953078{
30963079 int ret = 0 ;
3097- struct inet6_ifaddr * ifp ;
3080+ struct inet6_ifaddr * ifp = NULL ;
3081+ struct hlist_node * n ;
30983082 u8 hash = ipv6_addr_hash (addr );
3083+
30993084 read_lock_bh (& addrconf_hash_lock );
3100- for (ifp = inet6_addr_lst [hash ]; ifp ; ifp = ifp -> lst_next ) {
3085+ hlist_for_each_entry (ifp , n , & inet6_addr_lst [hash ], addr_lst ) {
31013086 if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
31023087 continue ;
31033088 if (ipv6_addr_equal (& ifp -> addr , addr ) &&
@@ -3118,6 +3103,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
31183103static void addrconf_verify (unsigned long foo )
31193104{
31203105 struct inet6_ifaddr * ifp ;
3106+ struct hlist_node * node ;
31213107 unsigned long now , next ;
31223108 int i ;
31233109
@@ -3131,7 +3117,7 @@ static void addrconf_verify(unsigned long foo)
31313117
31323118restart :
31333119 read_lock (& addrconf_hash_lock );
3134- for (ifp = inet6_addr_lst [i ]; ifp ; ifp = ifp -> lst_next ) {
3120+ hlist_for_each_entry (ifp , node , & inet6_addr_lst [i ], addr_lst ) {
31353121 unsigned long age ;
31363122#ifdef CONFIG_IPV6_PRIVACY
31373123 unsigned long regen_advance ;
@@ -4550,7 +4536,7 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier);
45504536
45514537int __init addrconf_init (void )
45524538{
4553- int err ;
4539+ int i , err ;
45544540
45554541 if ((err = ipv6_addr_label_init ()) < 0 ) {
45564542 printk (KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n" ,
@@ -4585,6 +4571,9 @@ int __init addrconf_init(void)
45854571 if (err )
45864572 goto errlo ;
45874573
4574+ for (i = 0 ; i < IN6_ADDR_HSIZE ; i ++ )
4575+ INIT_HLIST_HEAD (& inet6_addr_lst [i ]);
4576+
45884577 register_netdevice_notifier (& ipv6_dev_notf );
45894578
45904579 addrconf_verify (0 );
@@ -4613,7 +4602,6 @@ int __init addrconf_init(void)
46134602
46144603void addrconf_cleanup (void )
46154604{
4616- struct inet6_ifaddr * ifa ;
46174605 struct net_device * dev ;
46184606 int i ;
46194607
@@ -4634,18 +4622,8 @@ void addrconf_cleanup(void)
46344622 * Check hash table.
46354623 */
46364624 write_lock_bh (& addrconf_hash_lock );
4637- for (i = 0 ; i < IN6_ADDR_HSIZE ; i ++ ) {
4638- for (ifa = inet6_addr_lst [i ]; ifa ; ) {
4639- struct inet6_ifaddr * bifa ;
4640-
4641- bifa = ifa ;
4642- ifa = ifa -> lst_next ;
4643- printk (KERN_DEBUG "bug: IPv6 address leakage detected: ifa=%p\n" , bifa );
4644- /* Do not free it; something is wrong.
4645- Now we can investigate it with debugger.
4646- */
4647- }
4648- }
4625+ for (i = 0 ; i < IN6_ADDR_HSIZE ; i ++ )
4626+ WARN_ON (!hlist_empty (& inet6_addr_lst [i ]));
46494627 write_unlock_bh (& addrconf_hash_lock );
46504628
46514629 del_timer (& addr_chk_timer );
0 commit comments