All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: Jan Engelhardt <jengelh@medozas.de>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH 2/2] netfilter: xtables: inclusion of xt_condition
Date: Wed, 21 Apr 2010 15:07:19 +0200	[thread overview]
Message-ID: <4BCEF887.2070103@trash.net> (raw)
In-Reply-To: <1271845618-28569-3-git-send-email-jengelh@medozas.de>

Jan Engelhardt wrote:
> +static bool
> +condition_mt(const struct sk_buff *skb, const struct xt_match_param *par)
> +{
> +	const struct xt_condition_mtinfo *info = par->matchinfo;
> +	const struct condition_variable *var   = info->condvar;
> +	bool x;
> +
> +	rcu_read_lock();
> +	x = rcu_dereference(var->enabled);

At the risk of repeating myself, why is this using rcu_dereference()
for a boolean?

> +	rcu_read_unlock();
> +
> +	return x ^ info->invert;
> +}
> +
> +static int condition_mt_check(const struct xt_mtchk_param *par)
> +{
> +	struct xt_condition_mtinfo *info = par->matchinfo;
> +	struct condition_variable *var;
> +
> +	/* Forbid certain names */
> +	if (*info->name == '\0' || *info->name == '.' ||
> +	    info->name[sizeof(info->name)-1] != '\0' ||
> +	    memchr(info->name, '/', sizeof(info->name)) != NULL) {
> +		pr_info("name not allowed or too long: \"%.*s\"\n",
> +			(unsigned int)sizeof(info->name), info->name);
> +		return -EINVAL;
> +	}
> +	/*
> +	 * Let's acquire the lock, check for the condition and add it
> +	 * or increase the reference counter.
> +	 */
> +	if (mutex_lock_interruptible(&proc_lock) != 0)
> +		return -EINTR;

Also repeating myself - this seems like overkill, the section is
short and the mutex should basically never be contended.

> +	list_for_each_entry(var, &conditions_list, list) {
> +		if (strcmp(info->name, var->status_proc->name) == 0) {
> +			++var->refcount;
> +			mutex_unlock(&proc_lock);
> +			info->condvar = var;
> +			return 0;
> +		}
> +	}
> +
> +	/* At this point, we need to allocate a new condition variable. */
> +	var = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
> +	if (var == NULL) {
> +		mutex_unlock(&proc_lock);
> +		return -ENOMEM;
> +	}
> +
> +	/* Create the condition variable's proc file entry. */
> +	var->status_proc = create_proc_entry(info->name, condition_list_perms,
> +			   proc_net_condition);
> +	if (var->status_proc == NULL) {
> +		kfree(var);
> +		mutex_unlock(&proc_lock);
> +		return -ENOMEM;
> +	}
> +
> +	var->refcount = 1;
> +	var->enabled  = false;
> +	var->status_proc->data = var;
> +	wmb();

Please always comment the use of memory barriers.

> +	var->status_proc->read_proc  = condition_proc_read;
> +	var->status_proc->write_proc = condition_proc_write;
> +	list_add_rcu(&var->list, &conditions_list);

Still using rcu list variants for no reason.

> +	var->status_proc->uid = condition_uid_perms;
> +	var->status_proc->gid = condition_gid_perms;
> +	mutex_unlock(&proc_lock);
> +	info->condvar = var;
> +	return 0;
> +}
> +
> +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;
> +
> +	mutex_lock(&proc_lock);
> +	if (--var->refcount == 0) {
> +		list_del_rcu(&var->list);
> +		remove_proc_entry(var->status_proc->name, proc_net_condition);
> +		mutex_unlock(&proc_lock);
> +		/*
> +		 * synchronize_rcu() would be good enough, but
> +		 * synchronize_net() guarantees that no packet
> +		 * will go out with the old rule after
> +		 * succesful removal.
> +		 */
> +		synchronize_net();
> +		kfree(var);
> +		return;
> +	}
> +	mutex_unlock(&proc_lock);
> +}
> +
> +static struct xt_match condition_mt_reg __read_mostly = {
> +	.name       = "condition",
> +	.revision   = 1,
> +	.family     = NFPROTO_UNSPEC,
> +	.matchsize  = sizeof(struct xt_condition_mtinfo),
> +	.match      = condition_mt,
> +	.checkentry = condition_mt_check,
> +	.destroy    = condition_mt_destroy,
> +	.me         = THIS_MODULE,
> +};
> +
> +static const char *const dir_name = "nf_condition";
> +
> +static int __net_init condnet_mt_init(struct net *net)
> +{
> +	int ret;
> +
> +	proc_net_condition = proc_mkdir(dir_name, net->proc_net);
> +	if (proc_net_condition == NULL)
> +		return -EACCES;
> +
> +	ret = xt_register_match(&condition_mt_reg);
> +	if (ret < 0) {
> +		remove_proc_entry(dir_name, net->proc_net);
> +		return ret;

I'm not sure whether you accidentally posted an old version or
why there are none of the changes I asked for during the last
review. matches are not registered per namespace.

> +	}
> +
> +	return 0;
> +}
> +
> +static void __net_exit condnet_mt_exit(struct net *net)
> +{
> +	xt_unregister_match(&condition_mt_reg);
> +	remove_proc_entry(dir_name, net->proc_net);
> +}
> +
> +static struct pernet_operations condition_mt_netops = {
> +	.init = condnet_mt_init,
> +	.exit = condnet_mt_exit,
> +};
> +
> +static int __init condition_mt_init(void)
> +{
> +	mutex_init(&proc_lock);
> +	return register_pernet_subsys(&condition_mt_netops);
> +}
> +
> +static void __exit condition_mt_exit(void)
> +{
> +	unregister_pernet_subsys(&condition_mt_netops);
> +}
> +
> +module_init(condition_mt_init);
> +module_exit(condition_mt_exit);


      reply	other threads:[~2010-04-21 13:07 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-21 10:26 nf-next: sysrq and condition 20100421 Jan Engelhardt
2010-04-21 10:26 ` [PATCH 1/2] netfilter: xtables: inclusion of xt_SYSRQ Jan Engelhardt
2010-04-21 12:59   ` Patrick McHardy
2010-04-21 13:07     ` Jan Engelhardt
2010-04-21 13:17       ` Patrick McHardy
2010-04-21 13:35         ` Jan Engelhardt
2010-04-28 14:43           ` John Haxby
2010-04-28 14:54             ` John Haxby
2010-04-28 15:03               ` Jan Engelhardt
2010-04-28 15:50                 ` John Haxby
2010-07-25 16:49                 ` Jan Engelhardt
2010-07-25 18:13                   ` John Haxby
2012-01-05 13:19     ` Shan Wei
2010-04-21 10:26 ` [PATCH 2/2] netfilter: xtables: inclusion of xt_condition Jan Engelhardt
2010-04-21 13:07   ` Patrick McHardy [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BCEF887.2070103@trash.net \
    --to=kaber@trash.net \
    --cc=jengelh@medozas.de \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.