All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Engelhardt <jengelh@inai.de>
To: Daniel Golle <dgolle@cellrox.com>
Cc: jpa@google.com, john.stultz@linaro.org,
	containers@lists.linux-foundation.org,
	netfilter-devel@vger.kernel.org, orenl@cellrox.com,
	amir@cellrox.com
Subject: Re: [PATCH] xt_quota2: introduce support for netns
Date: Fri, 28 Feb 2014 03:33:03 +0100 (CET)	[thread overview]
Message-ID: <alpine.LSU.2.11.1402280327210.14757@nerf08.vanv.qr> (raw)
In-Reply-To: <20140225170034.GA10440@earthship.local.cellrox.com>

On Tuesday 2014-02-25 18:00, Daniel Golle wrote:

>Initialize a separate xt_quota2 instance for each network
>namespace so data limit can be set and enforced per persona.

> net/netfilter/xt_quota2.c | 127 +++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 102 insertions(+), 25 deletions(-)
>diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c
>index fb2ef46..bba78ec 100644
>--- a/net/netfilter/xt_quota2.c
>+++ b/net/netfilter/xt_quota2.c

This does not apply. Unfortunately, it does not apply either after
munging the paths back to original… the patch needs to be produced
with an original xt-a as base, or I need you to also hand me a clone
URL to grab your tree that has the fb2ef46 blob object.


$ quilt pu
Applying patch quilt-patches/0
patching file extensions/xt_quota2.c
Hunk #1 succeeded at 11 with fuzz 2.
Hunk #2 FAILED at 49.
Hunk #3 FAILED at 63.
Hunk #4 FAILED at 75.
Hunk #5 FAILED at 111.
Hunk #6 FAILED at 183.
Hunk #7 succeeded at 135 with fuzz 1 (offset -63 lines).
Hunk #8 FAILED at 208.
Hunk #9 FAILED at 220.
Hunk #10 succeeded at 177 (offset -78 lines).
Hunk #11 succeeded at 190 (offset -78 lines).
Hunk #12 succeeded at 204 (offset -78 lines).
Hunk #13 FAILED at 312.
Hunk #14 FAILED at 349.
9 out of 14 hunks FAILED -- rejects in file extensions/xt_quota2.c
Patch quilt-patches/0 does not apply (enforce with -f)


>@@ -11,6 +11,12 @@
>  *	it under the terms of the GNU General Public License; either
>  *	version 2 of the License, as published by the Free Software Foundation.
>  */
>+
>+#include <linux/nsproxy.h>
>+#include <net/net_namespace.h>
>+#include <net/netns/generic.h>
>+#include <net/dst.h>
>+
> #include <linux/list.h>
> #include <linux/module.h>
> #include <linux/proc_fs.h>
>@@ -43,13 +49,38 @@ module_param_named(event_num, qlog_nl_event, uint, S_IRUGO | S_IWUSR);
> MODULE_PARM_DESC(event_num,
> 		 "Event number for NETLINK_NFLOG message. 0 disables log."
> 		 "111 is what ipt_ULOG uses.");
>-static struct sock *nflognl;
> #endif
> 
>-static LIST_HEAD(counter_list);
>+struct quota2_net {
>+	struct list_head counter_list;
>+	struct proc_dir_entry *proc_xt_quota;
>+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
>+	struct sock *nflognl;
>+#endif
>+};
>+
>+static int quota2_net_id;
>+static inline struct quota2_net *quota2_pernet(struct net *net)
>+{
>+	return net_generic(net, quota2_net_id);
>+}
>+
>+/* from xt_TEE, should probably go into some common include */
>+static struct net *pick_net(const struct sk_buff *skb)
>+{
>+#ifdef CONFIG_NET_NS
>+	const struct dst_entry *dst;
>+	if (skb->dev != NULL)
>+		return dev_net(skb->dev);
>+	dst = skb_dst(skb);
>+	if (dst != NULL && dst->dev != NULL)
>+		return dev_net(dst->dev);
>+#endif
>+	return &init_net;
>+}
>+
> static DEFINE_SPINLOCK(counter_list_lock);
> 
>-static struct proc_dir_entry *proc_xt_quota;
> static unsigned int quota_list_perms = S_IRUGO | S_IWUSR;
> static unsigned int quota_list_uid   = 0;
> static unsigned int quota_list_gid   = 0;
>@@ -57,9 +88,9 @@ module_param_named(perms, quota_list_perms, uint, S_IRUGO | S_IWUSR);
> module_param_named(uid, quota_list_uid, uint, S_IRUGO | S_IWUSR);
> module_param_named(gid, quota_list_gid, uint, S_IRUGO | S_IWUSR);
> 
>-
> #ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
>-static void quota2_log(unsigned int hooknum,
>+static void quota2_log(struct net *net,
>+		       unsigned int hooknum,
> 		       const struct sk_buff *skb,
> 		       const struct net_device *in,
> 		       const struct net_device *out,
>@@ -69,7 +100,7 @@ static void quota2_log(unsigned int hooknum,
> 	struct sk_buff *log_skb;
> 	size_t size;
> 	struct nlmsghdr *nlh;
>-
>+	struct quota2_net *quota2_net = quota2_pernet(net);
> 	if (!qlog_nl_event)
> 		return;
> 
>@@ -105,13 +136,14 @@ static void quota2_log(unsigned int hooknum,
> 
> 	NETLINK_CB(log_skb).dst_group = 1;
> 	pr_debug("throwing 1 packets to netlink group 1\n");
>-	netlink_broadcast(nflognl, log_skb, 0, 1, GFP_ATOMIC);
>+	netlink_broadcast(quota2_net->nflognl, log_skb, 0, 1, GFP_ATOMIC);
> 
> nlmsg_failure:  /* Used within NLMSG_PUT() */
> 	pr_debug("xt_quota2: error during NLMSG_PUT\n");
> }
> #else
>-static void quota2_log(unsigned int hooknum,
>+static void quota2_log(struct net *net,
>+		       unsigned int hooknum,
> 		       const struct sk_buff *skb,
> 		       const struct net_device *in,
> 		       const struct net_device *out,
>@@ -177,11 +209,12 @@ q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon)
>  * @name:	name of counter
>  */
> static struct xt_quota_counter *
>-q2_get_counter(const struct xt_quota_mtinfo2 *q)
>+q2_get_counter(struct net *net, const struct xt_quota_mtinfo2 *q)
> {
> 	struct proc_dir_entry *p;
> 	struct xt_quota_counter *e = NULL;
> 	struct xt_quota_counter *new_e;
>+	struct quota2_net *quota2_net = quota2_pernet(net);
> 
> 	if (*q->name == '\0')
> 		return q2_new_counter(q, true);
>@@ -192,7 +225,7 @@ q2_get_counter(const struct xt_quota_mtinfo2 *q)
> 		goto out;
> 
> 	spin_lock_bh(&counter_list_lock);
>-	list_for_each_entry(e, &counter_list, list)
>+	list_for_each_entry(e, &quota2_net->counter_list, list)
> 		if (strcmp(e->name, q->name) == 0) {
> 			atomic_inc(&e->ref);
> 			spin_unlock_bh(&counter_list_lock);
>@@ -202,7 +235,7 @@ q2_get_counter(const struct xt_quota_mtinfo2 *q)
> 		}
> 	e = new_e;
> 	pr_debug("xt_quota2: new_counter name=%s", e->name);
>-	list_add_tail(&e->list, &counter_list);
>+	list_add_tail(&e->list, &quota2_net->counter_list);
> 	/* The entry having a refcount of 1 is not directly destructible.
> 	 * This func has not yet returned the new entry, thus iptables
> 	 * has not references for destroying this entry.
>@@ -214,7 +247,7 @@ q2_get_counter(const struct xt_quota_mtinfo2 *q)
> 
> 	/* create_proc_entry() is not spin_lock happy */
> 	p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms,
>-	                      proc_xt_quota);
>+	                      quota2_net->proc_xt_quota);
> 
> 	if (IS_ERR_OR_NULL(p)) {
> 		spin_lock_bh(&counter_list_lock);
>@@ -249,7 +282,7 @@ static int quota_mt2_check(const struct xt_mtchk_param *par)
> 		return -EINVAL;
> 	}
> 
>-	q->master = q2_get_counter(q);
>+	q->master = q2_get_counter(par->net, q);
> 	if (q->master == NULL) {
> 		printk(KERN_ERR "xt_quota.3: memory alloc failure\n");
> 		return -ENOMEM;
>@@ -262,6 +295,7 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
> {
> 	struct xt_quota_mtinfo2 *q = par->matchinfo;
> 	struct xt_quota_counter *e = q->master;
>+	struct quota2_net *quota2_net = quota2_pernet(par->net);
> 
> 	if (*q->name == '\0') {
> 		kfree(e);
>@@ -275,7 +309,7 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
> 	}
> 
> 	list_del(&e->list);
>-	remove_proc_entry(e->name, proc_xt_quota);
>+	remove_proc_entry(e->name, quota2_net->proc_xt_quota);
> 	spin_unlock_bh(&counter_list_lock);
> 	kfree(e);
> }
>@@ -305,7 +339,8 @@ quota_mt2(const struct sk_buff *skb, struct xt_action_param *par)
> 		} else {
> 			/* We are transitioning, log that fact. */
> 			if (e->quota) {
>-				quota2_log(par->hooknum,
>+				quota2_log(pick_net(skb),
>+					   par->hooknum,
> 					   skb,
> 					   par->in,
> 					   par->out,
>@@ -342,34 +377,76 @@ static struct xt_match quota_mt2_reg[] __read_mostly = {
> 	},
> };
> 
>-static int __init quota_mt2_init(void)
>+static int __net_init quota2_net_init(struct net *net)
> {
>-	int ret;
>-	pr_debug("xt_quota2: init()");
>-
>+	struct quota2_net *quota2_net = quota2_pernet(net);
>+	INIT_LIST_HEAD(&quota2_net->counter_list);
> #ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
>-	nflognl = netlink_kernel_create(&init_net,
>+	quota2_net->nflognl = netlink_kernel_create(net,
> 					NETLINK_NFLOG, 1, NULL,
> 					NULL, THIS_MODULE);
>-	if (!nflognl)
>+	if (quota2_net->nflognl == NULL)
> 		return -ENOMEM;
> #endif
> 
>-	proc_xt_quota = proc_mkdir("xt_quota", init_net.proc_net);
>-	if (proc_xt_quota == NULL)
>+	quota2_net->proc_xt_quota = proc_mkdir("xt_quota", net->proc_net);
>+	if (quota2_net->proc_xt_quota == NULL) {
>+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
>+		netlink_kernel_release(quota2_net->nflognl);
>+#endif
> 		return -EACCES;
>+	}
>+	return 0;
>+}
>+
>+static void __net_exit quota2_net_exit(struct net *net)
>+{
>+	struct quota2_net *quota2_net = quota2_pernet(net);
>+	struct xt_quota_counter *e = NULL;
>+	struct list_head *pos, *q;
>+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
>+	netlink_kernel_release(quota2_net->nflognl);
>+#endif
>+	remove_proc_entry("xt_quota", net->proc_net);
>+
>+	/* destroy counter_list while freeing it's content */
>+	spin_lock_bh(&counter_list_lock);
>+	list_for_each_safe(pos, q, &quota2_net->counter_list) {
>+		e = list_entry(pos, struct xt_quota_counter, list);
>+		list_del(pos);
>+		kfree(e);
>+	}
>+	spin_unlock_bh(&counter_list_lock);
>+}
>+
>+static struct pernet_operations quota2_net_ops = {
>+	.init   = quota2_net_init,
>+	.exit   = quota2_net_exit,
>+	.id     = &quota2_net_id,
>+	.size   = sizeof(struct quota2_net),
>+};
>+
>+static int __init quota_mt2_init(void)
>+{
>+	int ret;
>+	pr_debug("xt_quota2: init()");
>+
>+	ret = register_pernet_subsys(&quota2_net_ops);
>+	if (ret < 0)
>+		return ret;
> 
> 	ret = xt_register_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg));
> 	if (ret < 0)
>-		remove_proc_entry("xt_quota", init_net.proc_net);
>+		unregister_pernet_subsys(&quota2_net_ops);
> 	pr_debug("xt_quota2: init() %d", ret);
>+
> 	return ret;
> }
> 
> static void __exit quota_mt2_exit(void)
> {
> 	xt_unregister_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg));
>-	remove_proc_entry("xt_quota", init_net.proc_net);
>+	unregister_pernet_subsys(&quota2_net_ops);
> }
> 
> module_init(quota_mt2_init);
>-- 
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2014-02-28  2:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-25 17:00 [PATCH] xt_quota2: introduce support for netns Daniel Golle
2014-02-28  2:33 ` Jan Engelhardt [this message]
     [not found]   ` <alpine.LSU.2.11.1402280327210.14757-ePCkwj23jMPH9RFtKMg/Ng@public.gmane.org>
2014-03-05 12:00     ` Daniel Golle
     [not found] ` <20140225170034.GA10440-XJ2GtpFvYOzcMLnvn52sfNwH0Wv7OWhXQQ4Iyu8u01E@public.gmane.org>
2014-02-28  2:33   ` Jan Engelhardt

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=alpine.LSU.2.11.1402280327210.14757@nerf08.vanv.qr \
    --to=jengelh@inai.de \
    --cc=amir@cellrox.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=dgolle@cellrox.com \
    --cc=john.stultz@linaro.org \
    --cc=jpa@google.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=orenl@cellrox.com \
    /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.