@@ -117,23 +117,6 @@ htable_bits(u32 hashsize)
117117 return bits ;
118118}
119119
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-
137120static int
138121hbucket_elem_add (struct hbucket * n , u8 ahash_max , size_t dsize )
139122{
@@ -192,6 +175,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
192175#undef mtype_data_next
193176#undef mtype_elem
194177
178+ #undef mtype_ahash_destroy
179+ #undef mtype_ext_cleanup
195180#undef mtype_add_cidr
196181#undef mtype_del_cidr
197182#undef mtype_ahash_memsize
@@ -230,6 +215,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
230215#define mtype_data_list IPSET_TOKEN(MTYPE, _data_list)
231216#define mtype_data_next IPSET_TOKEN(MTYPE, _data_next)
232217#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)
233220#define mtype_add_cidr IPSET_TOKEN(MTYPE, _add_cidr)
234221#define mtype_del_cidr IPSET_TOKEN(MTYPE, _del_cidr)
235222#define mtype_ahash_memsize IPSET_TOKEN(MTYPE, _ahash_memsize)
@@ -359,6 +346,19 @@ mtype_ahash_memsize(const struct htype *h, const struct htable *t,
359346 return memsize ;
360347}
361348
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+
362362/* Flush a hash type of set: destroy all elements */
363363static void
364364mtype_flush (struct ip_set * set )
@@ -372,6 +372,8 @@ mtype_flush(struct ip_set *set)
372372 for (i = 0 ; i < jhash_size (t -> htable_bits ); i ++ ) {
373373 n = hbucket (t , i );
374374 if (n -> size ) {
375+ if (set -> extensions & IPSET_EXT_DESTROY )
376+ mtype_ext_cleanup (set , n );
375377 n -> size = n -> pos = 0 ;
376378 /* FIXME: use slab cache */
377379 kfree (n -> value );
@@ -383,6 +385,26 @@ mtype_flush(struct ip_set *set)
383385 h -> elements = 0 ;
384386}
385387
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+
386408/* Destroy a hash type of set */
387409static void
388410mtype_destroy (struct ip_set * set )
@@ -392,7 +414,7 @@ mtype_destroy(struct ip_set *set)
392414 if (set -> extensions & IPSET_EXT_TIMEOUT )
393415 del_timer_sync (& h -> gc );
394416
395- ahash_destroy ( rcu_dereference_bh_nfnl (h -> table ));
417+ mtype_ahash_destroy ( set , rcu_dereference_bh_nfnl (h -> table ));
396418#ifdef IP_SET_HASH_WITH_RBTREE
397419 rbtree_destroy (& h -> rbtree );
398420#endif
@@ -430,10 +452,6 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b)
430452 a -> extensions == b -> extensions ;
431453}
432454
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-
437455/* Delete expired elements from the hashtable */
438456static void
439457mtype_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)
456474 mtype_del_cidr (h , CIDR (data -> cidr ),
457475 nets_length , 0 );
458476#endif
477+ ip_set_ext_destroy (set , data );
459478 if (j != n -> pos - 1 )
460479 /* Not last one */
461480 memcpy (data ,
@@ -557,7 +576,7 @@ mtype_resize(struct ip_set *set, bool retried)
557576 mtype_data_reset_flags (data , & flags );
558577#endif
559578 read_unlock_bh (& set -> lock );
560- ahash_destroy ( t );
579+ mtype_ahash_destroy ( set , t );
561580 if (ret == - EAGAIN )
562581 goto retry ;
563582 return ret ;
@@ -578,7 +597,7 @@ mtype_resize(struct ip_set *set, bool retried)
578597
579598 pr_debug ("set %s resized from %u (%p) to %u (%p)\n" , set -> name ,
580599 orig -> htable_bits , orig , t -> htable_bits , t );
581- ahash_destroy ( orig );
600+ mtype_ahash_destroy ( set , orig );
582601
583602 return 0 ;
584603}
@@ -642,6 +661,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
642661 mtype_del_cidr (h , CIDR (data -> cidr ), NLEN (set -> family ), 0 );
643662 mtype_add_cidr (h , CIDR (d -> cidr ), NLEN (set -> family ), 0 );
644663#endif
664+ ip_set_ext_destroy (set , data );
645665 } else {
646666 /* Use/create a new slot */
647667 TUNE_AHASH_MAX (h , multi );
@@ -707,6 +727,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
707727#ifdef IP_SET_HASH_WITH_NETS
708728 mtype_del_cidr (h , CIDR (d -> cidr ), NLEN (set -> family ), 0 );
709729#endif
730+ ip_set_ext_destroy (set , data );
710731 if (n -> pos + AHASH_INIT_SIZE < n -> size ) {
711732 void * tmp = kzalloc ((n -> size - AHASH_INIT_SIZE )
712733 * set -> dsize ,
@@ -1033,7 +1054,7 @@ IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
10331054 rcu_assign_pointer (h -> table , t );
10341055
10351056 set -> data = h ;
1036- if (set -> family == NFPROTO_IPV4 ) {
1057+ if (set -> family == NFPROTO_IPV4 ) {
10371058 set -> variant = & IPSET_TOKEN (HTYPE , 4 _variant );
10381059 set -> dsize = ip_set_elem_len (set , tb ,
10391060 sizeof (struct IPSET_TOKEN (HTYPE , 4 _elem )));
0 commit comments