@@ -126,7 +126,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev);
126
126
/*
127
127
* Configured unicast address hash table
128
128
*/
129
- static struct inet6_ifaddr * inet6_addr_lst [IN6_ADDR_HSIZE ];
129
+ static struct hlist_head inet6_addr_lst [IN6_ADDR_HSIZE ];
130
130
static DEFINE_RWLOCK (addrconf_hash_lock );
131
131
132
132
static void addrconf_verify (unsigned long );
@@ -528,7 +528,7 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
528
528
void inet6_ifa_finish_destroy (struct inet6_ifaddr * ifp )
529
529
{
530
530
WARN_ON (ifp -> if_next != NULL );
531
- WARN_ON (ifp -> lst_next != NULL );
531
+ WARN_ON (! hlist_unhashed ( & ifp -> addr_lst ) );
532
532
533
533
#ifdef NET_REFCNT_DEBUG
534
534
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,
643
643
644
644
spin_lock_init (& ifa -> lock );
645
645
init_timer (& ifa -> timer );
646
+ INIT_HLIST_NODE (& ifa -> addr_lst );
646
647
ifa -> timer .data = (unsigned long ) ifa ;
647
648
ifa -> scope = scope ;
648
649
ifa -> prefix_len = pfxlen ;
@@ -669,8 +670,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
669
670
/* Add to big hash table */
670
671
hash = ipv6_addr_hash (addr );
671
672
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 ]);
674
674
in6_ifa_hold (ifa );
675
675
write_unlock (& addrconf_hash_lock );
676
676
@@ -718,15 +718,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
718
718
ifp -> dead = 1 ;
719
719
720
720
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 );
730
723
write_unlock_bh (& addrconf_hash_lock );
731
724
732
725
write_lock_bh (& idev -> lock );
@@ -1277,11 +1270,12 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
1277
1270
int ipv6_chk_addr (struct net * net , struct in6_addr * addr ,
1278
1271
struct net_device * dev , int strict )
1279
1272
{
1280
- struct inet6_ifaddr * ifp ;
1273
+ struct inet6_ifaddr * ifp = NULL ;
1274
+ struct hlist_node * node ;
1281
1275
u8 hash = ipv6_addr_hash (addr );
1282
1276
1283
1277
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 ) {
1285
1279
if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
1286
1280
continue ;
1287
1281
if (ipv6_addr_equal (& ifp -> addr , addr ) &&
@@ -1300,10 +1294,11 @@ static
1300
1294
int ipv6_chk_same_addr (struct net * net , const struct in6_addr * addr ,
1301
1295
struct net_device * dev )
1302
1296
{
1303
- struct inet6_ifaddr * ifp ;
1297
+ struct inet6_ifaddr * ifp ;
1298
+ struct hlist_node * node ;
1304
1299
u8 hash = ipv6_addr_hash (addr );
1305
1300
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 ) {
1307
1302
if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
1308
1303
continue ;
1309
1304
if (ipv6_addr_equal (& ifp -> addr , addr )) {
@@ -1342,11 +1337,12 @@ EXPORT_SYMBOL(ipv6_chk_prefix);
1342
1337
struct inet6_ifaddr * ipv6_get_ifaddr (struct net * net , const struct in6_addr * addr ,
1343
1338
struct net_device * dev , int strict )
1344
1339
{
1345
- struct inet6_ifaddr * ifp ;
1340
+ struct inet6_ifaddr * ifp = NULL ;
1341
+ struct hlist_node * node ;
1346
1342
u8 hash = ipv6_addr_hash (addr );
1347
1343
1348
1344
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 ) {
1350
1346
if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
1351
1347
continue ;
1352
1348
if (ipv6_addr_equal (& ifp -> addr , addr )) {
@@ -2612,7 +2608,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2612
2608
struct inet6_dev * idev ;
2613
2609
struct inet6_ifaddr * ifa , * keep_list , * * bifa ;
2614
2610
struct net * net = dev_net (dev );
2615
- int i ;
2616
2611
2617
2612
ASSERT_RTNL ();
2618
2613
@@ -2637,25 +2632,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2637
2632
2638
2633
}
2639
2634
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
-
2659
2635
write_lock_bh (& idev -> lock );
2660
2636
2661
2637
/* Step 3: clear flags for stateless addrconf */
@@ -2721,6 +2697,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2721
2697
}
2722
2698
write_unlock_bh (& idev -> lock );
2723
2699
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
+
2724
2706
__ipv6_ifa_notify (RTM_DELADDR , ifa );
2725
2707
atomic_notifier_call_chain (& inet6addr_chain , NETDEV_DOWN , ifa );
2726
2708
in6_ifa_put (ifa );
@@ -2963,36 +2945,37 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
2963
2945
struct net * net = seq_file_net (seq );
2964
2946
2965
2947
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
+ }
2972
2954
}
2973
- return ifa ;
2955
+ return NULL ;
2974
2956
}
2975
2957
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 )
2977
2960
{
2978
2961
struct if6_iter_state * state = seq -> private ;
2979
2962
struct net * net = seq_file_net (seq );
2963
+ struct hlist_node * n = & ifa -> addr_lst ;
2980
2964
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 ;
2988
2968
}
2989
2969
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
+ }
2993
2976
}
2994
2977
2995
- return ifa ;
2978
+ return NULL ;
2996
2979
}
2997
2980
2998
2981
static struct inet6_ifaddr * if6_get_idx (struct seq_file * seq , loff_t pos )
@@ -3094,10 +3077,12 @@ void if6_proc_exit(void)
3094
3077
int ipv6_chk_home_addr (struct net * net , struct in6_addr * addr )
3095
3078
{
3096
3079
int ret = 0 ;
3097
- struct inet6_ifaddr * ifp ;
3080
+ struct inet6_ifaddr * ifp = NULL ;
3081
+ struct hlist_node * n ;
3098
3082
u8 hash = ipv6_addr_hash (addr );
3083
+
3099
3084
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 ) {
3101
3086
if (!net_eq (dev_net (ifp -> idev -> dev ), net ))
3102
3087
continue ;
3103
3088
if (ipv6_addr_equal (& ifp -> addr , addr ) &&
@@ -3118,6 +3103,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
3118
3103
static void addrconf_verify (unsigned long foo )
3119
3104
{
3120
3105
struct inet6_ifaddr * ifp ;
3106
+ struct hlist_node * node ;
3121
3107
unsigned long now , next ;
3122
3108
int i ;
3123
3109
@@ -3131,7 +3117,7 @@ static void addrconf_verify(unsigned long foo)
3131
3117
3132
3118
restart :
3133
3119
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 ) {
3135
3121
unsigned long age ;
3136
3122
#ifdef CONFIG_IPV6_PRIVACY
3137
3123
unsigned long regen_advance ;
@@ -4550,7 +4536,7 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier);
4550
4536
4551
4537
int __init addrconf_init (void )
4552
4538
{
4553
- int err ;
4539
+ int i , err ;
4554
4540
4555
4541
if ((err = ipv6_addr_label_init ()) < 0 ) {
4556
4542
printk (KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n" ,
@@ -4585,6 +4571,9 @@ int __init addrconf_init(void)
4585
4571
if (err )
4586
4572
goto errlo ;
4587
4573
4574
+ for (i = 0 ; i < IN6_ADDR_HSIZE ; i ++ )
4575
+ INIT_HLIST_HEAD (& inet6_addr_lst [i ]);
4576
+
4588
4577
register_netdevice_notifier (& ipv6_dev_notf );
4589
4578
4590
4579
addrconf_verify (0 );
@@ -4613,7 +4602,6 @@ int __init addrconf_init(void)
4613
4602
4614
4603
void addrconf_cleanup (void )
4615
4604
{
4616
- struct inet6_ifaddr * ifa ;
4617
4605
struct net_device * dev ;
4618
4606
int i ;
4619
4607
@@ -4634,18 +4622,8 @@ void addrconf_cleanup(void)
4634
4622
* Check hash table.
4635
4623
*/
4636
4624
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 ]));
4649
4627
write_unlock_bh (& addrconf_hash_lock );
4650
4628
4651
4629
del_timer (& addr_chk_timer );
0 commit comments