Hello A few years ago I add network namespace to extension condition. I review this changes again and make changes again. This is better version. diff --git a/extensions/xt_condition.c b/extensions/xt_condition.c index 8227c5d..c5b0df3 100644 --- a/extensions/xt_condition.c +++ b/extensions/xt_condition.c @@ -65,12 +65,11 @@ static DEFINE_MUTEX(proc_lock); struct condition_net { struct list_head conditions_list; struct proc_dir_entry *proc_net_condition; - bool after_clear; }; static int condition_net_id; -static inline struct condition_net *condition_pernet(struct net *net) +static inline struct condition_net *get_condition_pernet(struct net *net) { return net_generic(net, condition_net_id); } @@ -132,7 +131,7 @@ static int condition_mt_check(const struct xt_mtchk_param *par) { struct xt_condition_mtinfo *info = par->matchinfo; struct condition_variable *var; - struct condition_net *condition_net = condition_pernet(par->net); + struct condition_net *condition_net = get_condition_pernet(par->net); /* Forbid certain names */ if (*info->name == '\0' || *info->name == '.' || @@ -190,13 +189,10 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_condition_mtinfo *info = par->matchinfo; struct condition_variable *var = info->condvar; - struct condition_net *cnet = condition_pernet(par->net); - - if (cnet->after_clear) - return; - + struct condition_net *cnet = get_condition_pernet(par->net); + mutex_lock(&proc_lock); - if (--var->refcount == 0) { + if (--var->refcount == 0 && !list_empty_careful(&cnet->conditions_list)) { list_del(&var->list); remove_proc_entry(var->name, cnet->proc_net_condition); mutex_unlock(&proc_lock); @@ -233,18 +229,17 @@ static const char *const dir_name = "nf_condition"; static int __net_init condition_net_init(struct net *net) { - struct condition_net *condition_net = condition_pernet(net); + struct condition_net *condition_net = get_condition_pernet(net); INIT_LIST_HEAD(&condition_net->conditions_list); condition_net->proc_net_condition = proc_mkdir(dir_name, net->proc_net); if (condition_net->proc_net_condition == NULL) return -EACCES; - condition_net->after_clear = 0; return 0; } static void __net_exit condition_net_exit(struct net *net) { - struct condition_net *condition_net = condition_pernet(net); + struct condition_net *condition_net = get_condition_pernet(net); struct list_head *pos, *q; struct condition_variable *var = NULL; @@ -256,7 +251,6 @@ static void __net_exit condition_net_exit(struct net *net) kfree(var); } mutex_unlock(&proc_lock); - condition_net->after_clear = true; } static struct pernet_operations condition_net_ops = { -- Grzegorz Kuczyński