@@ -262,18 +262,26 @@ static void tree_nodes_free(struct rb_root *root,
262262}
263263
264264static unsigned int
265- count_tree (struct net * net , struct rb_root * root ,
266- const u32 * key , u8 keylen ,
265+ count_tree (struct net * net ,
266+ struct nf_conncount_data * data ,
267+ const u32 * key ,
267268 const struct nf_conntrack_tuple * tuple ,
268269 const struct nf_conntrack_zone * zone )
269270{
270271 struct nf_conncount_rb * gc_nodes [CONNCOUNT_GC_MAX_NODES ];
272+ struct rb_root * root ;
271273 struct rb_node * * rbnode , * parent ;
272274 struct nf_conncount_rb * rbconn ;
273275 struct nf_conncount_tuple * conn ;
274- unsigned int gc_count ;
276+ unsigned int gc_count , hash ;
275277 bool no_gc = false;
278+ unsigned int count = 0 ;
279+ u8 keylen = data -> keylen ;
276280
281+ hash = jhash2 (key , data -> keylen , conncount_rnd ) % CONNCOUNT_SLOTS ;
282+ root = & data -> root [hash ];
283+
284+ spin_lock_bh (& nf_conncount_locks [hash % CONNCOUNT_LOCK_SLOTS ]);
277285 restart :
278286 gc_count = 0 ;
279287 parent = NULL ;
@@ -292,20 +300,20 @@ count_tree(struct net *net, struct rb_root *root,
292300 rbnode = & ((* rbnode )-> rb_right );
293301 } else {
294302 /* same source network -> be counted! */
295- unsigned int count ;
296-
297303 nf_conncount_lookup (net , & rbconn -> list , tuple , zone ,
298304 & addit );
299305 count = rbconn -> list .count ;
300306
301307 tree_nodes_free (root , gc_nodes , gc_count );
302308 if (!addit )
303- return count ;
309+ goto out_unlock ;
304310
305311 if (!nf_conncount_add (& rbconn -> list , tuple , zone ))
306- return 0 ; /* hotdrop */
312+ count = 0 ; /* hotdrop */
313+ goto out_unlock ;
307314
308- return count + 1 ;
315+ count ++ ;
316+ goto out_unlock ;
309317 }
310318
311319 if (no_gc || gc_count >= ARRAY_SIZE (gc_nodes ))
@@ -328,18 +336,18 @@ count_tree(struct net *net, struct rb_root *root,
328336 goto restart ;
329337 }
330338
339+ count = 0 ;
331340 if (!tuple )
332- return 0 ;
333-
341+ goto out_unlock ;
334342 /* no match, need to insert new node */
335343 rbconn = kmem_cache_alloc (conncount_rb_cachep , GFP_ATOMIC );
336344 if (rbconn == NULL )
337- return 0 ;
345+ goto out_unlock ;
338346
339347 conn = kmem_cache_alloc (conncount_conn_cachep , GFP_ATOMIC );
340348 if (conn == NULL ) {
341349 kmem_cache_free (conncount_rb_cachep , rbconn );
342- return 0 ;
350+ goto out_unlock ;
343351 }
344352
345353 conn -> tuple = * tuple ;
@@ -348,10 +356,13 @@ count_tree(struct net *net, struct rb_root *root,
348356
349357 nf_conncount_list_init (& rbconn -> list );
350358 list_add (& conn -> node , & rbconn -> list .head );
359+ count = 1 ;
351360
352361 rb_link_node (& rbconn -> node , parent , rbnode );
353362 rb_insert_color (& rbconn -> node , root );
354- return 1 ;
363+ out_unlock :
364+ spin_unlock_bh (& nf_conncount_locks [hash % CONNCOUNT_LOCK_SLOTS ]);
365+ return count ;
355366}
356367
357368/* Count and return number of conntrack entries in 'net' with particular 'key'.
@@ -363,20 +374,7 @@ unsigned int nf_conncount_count(struct net *net,
363374 const struct nf_conntrack_tuple * tuple ,
364375 const struct nf_conntrack_zone * zone )
365376{
366- struct rb_root * root ;
367- int count ;
368- u32 hash ;
369-
370- hash = jhash2 (key , data -> keylen , conncount_rnd ) % CONNCOUNT_SLOTS ;
371- root = & data -> root [hash ];
372-
373- spin_lock_bh (& nf_conncount_locks [hash % CONNCOUNT_LOCK_SLOTS ]);
374-
375- count = count_tree (net , root , key , data -> keylen , tuple , zone );
376-
377- spin_unlock_bh (& nf_conncount_locks [hash % CONNCOUNT_LOCK_SLOTS ]);
378-
379- return count ;
377+ return count_tree (net , data , key , tuple , zone );
380378}
381379EXPORT_SYMBOL_GPL (nf_conncount_count );
382380
0 commit comments