@@ -117,23 +117,6 @@ htable_bits(u32 hashsize)
117
117
return bits ;
118
118
}
119
119
120
- /* Destroy the hashtable part of the set */
121
- static void
122
- ahash_destroy (struct htable * t )
123
- {
124
- struct hbucket * n ;
125
- u32 i ;
126
-
127
- for (i = 0 ; i < jhash_size (t -> htable_bits ); i ++ ) {
128
- n = hbucket (t , i );
129
- if (n -> size )
130
- /* FIXME: use slab cache */
131
- kfree (n -> value );
132
- }
133
-
134
- ip_set_free (t );
135
- }
136
-
137
120
static int
138
121
hbucket_elem_add (struct hbucket * n , u8 ahash_max , size_t dsize )
139
122
{
@@ -192,6 +175,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
192
175
#undef mtype_data_next
193
176
#undef mtype_elem
194
177
178
+ #undef mtype_ahash_destroy
179
+ #undef mtype_ext_cleanup
195
180
#undef mtype_add_cidr
196
181
#undef mtype_del_cidr
197
182
#undef mtype_ahash_memsize
@@ -230,6 +215,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
230
215
#define mtype_data_list IPSET_TOKEN(MTYPE, _data_list)
231
216
#define mtype_data_next IPSET_TOKEN(MTYPE, _data_next)
232
217
#define mtype_elem IPSET_TOKEN(MTYPE, _elem)
218
+ #define mtype_ahash_destroy IPSET_TOKEN(MTYPE, _ahash_destroy)
219
+ #define mtype_ext_cleanup IPSET_TOKEN(MTYPE, _ext_cleanup)
233
220
#define mtype_add_cidr IPSET_TOKEN(MTYPE, _add_cidr)
234
221
#define mtype_del_cidr IPSET_TOKEN(MTYPE, _del_cidr)
235
222
#define mtype_ahash_memsize IPSET_TOKEN(MTYPE, _ahash_memsize)
@@ -359,6 +346,19 @@ mtype_ahash_memsize(const struct htype *h, const struct htable *t,
359
346
return memsize ;
360
347
}
361
348
349
+ /* Get the ith element from the array block n */
350
+ #define ahash_data (n , i , dsize ) \
351
+ ((struct mtype_elem *)((n)->value + ((i) * (dsize))))
352
+
353
+ static void
354
+ mtype_ext_cleanup (struct ip_set * set , struct hbucket * n )
355
+ {
356
+ int i ;
357
+
358
+ for (i = 0 ; i < n -> pos ; i ++ )
359
+ ip_set_ext_destroy (set , ahash_data (n , i , set -> dsize ));
360
+ }
361
+
362
362
/* Flush a hash type of set: destroy all elements */
363
363
static void
364
364
mtype_flush (struct ip_set * set )
@@ -372,6 +372,8 @@ mtype_flush(struct ip_set *set)
372
372
for (i = 0 ; i < jhash_size (t -> htable_bits ); i ++ ) {
373
373
n = hbucket (t , i );
374
374
if (n -> size ) {
375
+ if (set -> extensions & IPSET_EXT_DESTROY )
376
+ mtype_ext_cleanup (set , n );
375
377
n -> size = n -> pos = 0 ;
376
378
/* FIXME: use slab cache */
377
379
kfree (n -> value );
@@ -383,6 +385,26 @@ mtype_flush(struct ip_set *set)
383
385
h -> elements = 0 ;
384
386
}
385
387
388
+ /* Destroy the hashtable part of the set */
389
+ static void
390
+ mtype_ahash_destroy (struct ip_set * set , struct htable * t )
391
+ {
392
+ struct hbucket * n ;
393
+ u32 i ;
394
+
395
+ for (i = 0 ; i < jhash_size (t -> htable_bits ); i ++ ) {
396
+ n = hbucket (t , i );
397
+ if (n -> size ) {
398
+ if (set -> extensions & IPSET_EXT_DESTROY )
399
+ mtype_ext_cleanup (set , n );
400
+ /* FIXME: use slab cache */
401
+ kfree (n -> value );
402
+ }
403
+ }
404
+
405
+ ip_set_free (t );
406
+ }
407
+
386
408
/* Destroy a hash type of set */
387
409
static void
388
410
mtype_destroy (struct ip_set * set )
@@ -392,7 +414,7 @@ mtype_destroy(struct ip_set *set)
392
414
if (set -> extensions & IPSET_EXT_TIMEOUT )
393
415
del_timer_sync (& h -> gc );
394
416
395
- ahash_destroy ( rcu_dereference_bh_nfnl (h -> table ));
417
+ mtype_ahash_destroy ( set , rcu_dereference_bh_nfnl (h -> table ));
396
418
#ifdef IP_SET_HASH_WITH_RBTREE
397
419
rbtree_destroy (& h -> rbtree );
398
420
#endif
@@ -430,10 +452,6 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b)
430
452
a -> extensions == b -> extensions ;
431
453
}
432
454
433
- /* Get the ith element from the array block n */
434
- #define ahash_data (n , i , dsize ) \
435
- ((struct mtype_elem *)((n)->value + ((i) * (dsize))))
436
-
437
455
/* Delete expired elements from the hashtable */
438
456
static void
439
457
mtype_expire (struct ip_set * set , struct htype * h , u8 nets_length , size_t dsize )
@@ -456,6 +474,7 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
456
474
mtype_del_cidr (h , CIDR (data -> cidr ),
457
475
nets_length , 0 );
458
476
#endif
477
+ ip_set_ext_destroy (set , data );
459
478
if (j != n -> pos - 1 )
460
479
/* Not last one */
461
480
memcpy (data ,
@@ -557,7 +576,7 @@ mtype_resize(struct ip_set *set, bool retried)
557
576
mtype_data_reset_flags (data , & flags );
558
577
#endif
559
578
read_unlock_bh (& set -> lock );
560
- ahash_destroy ( t );
579
+ mtype_ahash_destroy ( set , t );
561
580
if (ret == - EAGAIN )
562
581
goto retry ;
563
582
return ret ;
@@ -578,7 +597,7 @@ mtype_resize(struct ip_set *set, bool retried)
578
597
579
598
pr_debug ("set %s resized from %u (%p) to %u (%p)\n" , set -> name ,
580
599
orig -> htable_bits , orig , t -> htable_bits , t );
581
- ahash_destroy ( orig );
600
+ mtype_ahash_destroy ( set , orig );
582
601
583
602
return 0 ;
584
603
}
@@ -642,6 +661,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
642
661
mtype_del_cidr (h , CIDR (data -> cidr ), NLEN (set -> family ), 0 );
643
662
mtype_add_cidr (h , CIDR (d -> cidr ), NLEN (set -> family ), 0 );
644
663
#endif
664
+ ip_set_ext_destroy (set , data );
645
665
} else {
646
666
/* Use/create a new slot */
647
667
TUNE_AHASH_MAX (h , multi );
@@ -707,6 +727,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
707
727
#ifdef IP_SET_HASH_WITH_NETS
708
728
mtype_del_cidr (h , CIDR (d -> cidr ), NLEN (set -> family ), 0 );
709
729
#endif
730
+ ip_set_ext_destroy (set , data );
710
731
if (n -> pos + AHASH_INIT_SIZE < n -> size ) {
711
732
void * tmp = kzalloc ((n -> size - AHASH_INIT_SIZE )
712
733
* set -> dsize ,
@@ -1033,7 +1054,7 @@ IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
1033
1054
rcu_assign_pointer (h -> table , t );
1034
1055
1035
1056
set -> data = h ;
1036
- if (set -> family == NFPROTO_IPV4 ) {
1057
+ if (set -> family == NFPROTO_IPV4 ) {
1037
1058
set -> variant = & IPSET_TOKEN (HTYPE , 4 _variant );
1038
1059
set -> dsize = ip_set_elem_len (set , tb ,
1039
1060
sizeof (struct IPSET_TOKEN (HTYPE , 4 _elem )));
0 commit comments