diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index d2ff15a..747d52d 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -85,6 +85,7 @@ struct recent_net { struct list_head tables; #ifdef CONFIG_PROC_FS struct proc_dir_entry *xt_recent; + int clean; #endif }; @@ -398,7 +399,8 @@ static void recent_mt_destroy(const struct xt_mtdtor_param *par) list_del(&t->list); spin_unlock_bh(&recent_lock); #ifdef CONFIG_PROC_FS - remove_proc_entry(t->name, recent_net->xt_recent); + if(!recent_net->clean) + remove_proc_entry(t->name, recent_net->xt_recent); #endif recent_table_flush(t); kfree(t); @@ -599,15 +601,26 @@ static int __net_init recent_net_init(struct net *net) { struct recent_net *recent_net = recent_pernet(net); +#ifdef CONFIG_PROC_FS + recent_net->clean = 0; +#endif INIT_LIST_HEAD(&recent_net->tables); return recent_proc_net_init(net); } static void __net_exit recent_net_exit(struct net *net) { +#ifdef CONFIG_PROC_FS struct recent_net *recent_net = recent_pernet(net); + struct recent_table *t; - BUG_ON(!list_empty(&recent_net->tables)); + spin_lock_bh(&recent_lock); + recent_net->clean = 1; + list_for_each_entry(t, &recent_net->tables, list) { + remove_proc_entry(t->name, recent_net->xt_recent); + } + spin_unlock_bh(&recent_lock); +#endif recent_proc_net_exit(net); }