netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] netlink: netlink_dump_start takes pointer to data
@ 2012-02-25  0:30 pablo
  2012-02-25  0:30 ` [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start() pablo
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: pablo @ 2012-02-25  0:30 UTC (permalink / raw)
  To: netdev; +Cc: netfilter-devel, davem

From: Pablo Neira Ayuso <pablo@netfilter.org>

Hi!

This is the second version of the extension for netlink_dump_start
to take one data pointer that can be pass to the dump callback.

These changes allow to filter by the ctmark in ctnetlink.

Suggestion from Davem has been included in this patchset.

Thanks!

Pablo Neira Ayuso (3):
  netlink: add netlink_dump_control structure for netlink_dump_start()
  netlink: allow to pass data pointer to netlink_dump_start() callback
  netfilter: ctnetlink: support kernel-space dump filtering by ctmark

 crypto/crypto_user.c                          |   10 +++-
 drivers/infiniband/core/netlink.c             |   10 +++-
 include/linux/netfilter/nfnetlink_conntrack.h |    1 +
 include/linux/netlink.h                       |   12 ++++-
 net/core/rtnetlink.c                          |    9 +++-
 net/ipv4/inet_diag.c                          |   18 ++++++---
 net/netfilter/ipset/ip_set_core.c             |   10 +++-
 net/netfilter/nf_conntrack_netlink.c          |   50 ++++++++++++++++++++++---
 net/netfilter/nfnetlink_acct.c                |    6 ++-
 net/netlink/af_netlink.c                      |   12 ++---
 net/netlink/genetlink.c                       |    9 +++-
 net/unix/diag.c                               |   10 +++--
 net/xfrm/xfrm_user.c                          |    9 +++-
 13 files changed, 123 insertions(+), 43 deletions(-)

-- 
1.7.7.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start()
  2012-02-25  0:30 [PATCH 0/3] netlink: netlink_dump_start takes pointer to data pablo
@ 2012-02-25  0:30 ` pablo
  2012-02-25  1:12   ` Jan Engelhardt
  2012-02-26 19:26   ` David Miller
  2012-02-25  0:30 ` [PATCH 2/3] netlink: allow to pass data pointer to netlink_dump_start() callback pablo
  2012-02-25  0:30 ` [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark pablo
  2 siblings, 2 replies; 10+ messages in thread
From: pablo @ 2012-02-25  0:30 UTC (permalink / raw)
  To: netdev; +Cc: netfilter-devel, davem

From: Pablo Neira Ayuso <pablo@netfilter.org>

Davem considers that the argument list of this interface is getting
out of control. This patch tries to address this issue following
his proposal:

struct netlink_dump_control c = { .dump = dump, .done = done, ... };

netlink_dump_start(..., &c);

Suggested by David S. Miller.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 crypto/crypto_user.c                 |   10 +++++++---
 drivers/infiniband/core/netlink.c    |   10 +++++++---
 include/linux/netlink.h              |   10 +++++++---
 net/core/rtnetlink.c                 |    9 +++++++--
 net/ipv4/inet_diag.c                 |   18 ++++++++++++------
 net/netfilter/ipset/ip_set_core.c    |   10 +++++++---
 net/netfilter/nf_conntrack_netlink.c |   18 ++++++++++++------
 net/netfilter/nfnetlink_acct.c       |    6 ++++--
 net/netlink/af_netlink.c             |   11 ++++-------
 net/netlink/genetlink.c              |    9 +++++++--
 net/unix/diag.c                      |   10 ++++++----
 net/xfrm/xfrm_user.c                 |    9 +++++++--
 12 files changed, 87 insertions(+), 43 deletions(-)

diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 16f8693..b6ac138 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -389,9 +389,13 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 	    (nlh->nlmsg_flags & NLM_F_DUMP))) {
 		if (link->dump == NULL)
 			return -EINVAL;
-
-		return netlink_dump_start(crypto_nlsk, skb, nlh,
-					  link->dump, link->done, 0);
+		{
+			struct netlink_dump_control c = {
+				.dump = link->dump,
+				.done = link->done,
+			};
+			return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
+		}
 	}
 
 	err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index d1c8196..396e293 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -147,9 +147,13 @@ static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 			if (op < 0 || op >= client->nops ||
 			    !client->cb_table[RDMA_NL_GET_OP(op)].dump)
 				return -EINVAL;
-			return netlink_dump_start(nls, skb, nlh,
-						  client->cb_table[op].dump,
-						  NULL, 0);
+
+			{
+				struct netlink_dump_control c = {
+					.dump = client->cb_table[op].dump,
+				};
+				return netlink_dump_start(nls, skb, nlh, &c);
+			}
 		}
 	}
 
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index a390e9d..1f8c1a9 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -248,11 +248,15 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
 #define NLMSG_PUT(skb, pid, seq, type, len) \
 	NLMSG_NEW(skb, pid, seq, type, len, 0)
 
+struct netlink_dump_control {
+	int (*dump)(struct sk_buff *skb, struct netlink_callback *);
+	int (*done)(struct netlink_callback*);
+	u16 min_dump_alloc;
+};
+
 extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 			      const struct nlmsghdr *nlh,
-			      int (*dump)(struct sk_buff *skb, struct netlink_callback*),
-			      int (*done)(struct netlink_callback*),
-			      u16 min_dump_alloc);
+			      struct netlink_dump_control *control);
 
 
 #define NL_NONROOT_RECV 0x1
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 65aebd4..7aef62e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1981,8 +1981,13 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 		__rtnl_unlock();
 		rtnl = net->rtnl;
-		err = netlink_dump_start(rtnl, skb, nlh, dumpit,
-					 NULL, min_dump_alloc);
+		{
+			struct netlink_dump_control c = {
+				.dump		= dumpit,
+				.min_dump_alloc	= min_dump_alloc,
+			};
+			err = netlink_dump_start(rtnl, skb, nlh, &c);
+		}
 		rtnl_lock();
 		return err;
 	}
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index fcf2818..8d25a1c 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -960,9 +960,12 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
 			    inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
 				return -EINVAL;
 		}
-
-		return netlink_dump_start(sock_diag_nlsk, skb, nlh,
-					  inet_diag_dump_compat, NULL, 0);
+		{
+			struct netlink_dump_control c = {
+				.dump = inet_diag_dump_compat,
+			};
+			return netlink_dump_start(sock_diag_nlsk, skb, nlh, &c);
+		}
 	}
 
 	return inet_diag_get_exact_compat(skb, nlh);
@@ -985,9 +988,12 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
 			    inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
 				return -EINVAL;
 		}
-
-		return netlink_dump_start(sock_diag_nlsk, skb, h,
-					  inet_diag_dump, NULL, 0);
+		{
+			struct netlink_dump_control c = {
+				.dump = inet_diag_dump,
+			};
+			return netlink_dump_start(sock_diag_nlsk, skb, h, &c);
+		}
 	}
 
 	return inet_diag_get_exact(skb, h, (struct inet_diag_req_v2 *)NLMSG_DATA(h));
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index aeee9bd..e6c1c96 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1162,9 +1162,13 @@ ip_set_dump(struct sock *ctnl, struct sk_buff *skb,
 	if (unlikely(protocol_failed(attr)))
 		return -IPSET_ERR_PROTOCOL;
 
-	return netlink_dump_start(ctnl, skb, nlh,
-				  ip_set_dump_start,
-				  ip_set_dump_done, 0);
+	{
+		struct netlink_dump_control c = {
+			.dump = ip_set_dump_start,
+			.done = ip_set_dump_done,
+		};
+		return netlink_dump_start(ctnl, skb, nlh, &c);
+	}
 }
 
 /* Add, del and test */
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 33a7bb4..dd4aaba 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -977,9 +977,13 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
 	u16 zone;
 	int err;
 
-	if (nlh->nlmsg_flags & NLM_F_DUMP)
-		return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
-					  ctnetlink_done, 0);
+	if (nlh->nlmsg_flags & NLM_F_DUMP) {
+		struct netlink_dump_control c = {
+			.dump = ctnetlink_dump_table,
+			.done = ctnetlink_done,
+		};
+		return netlink_dump_start(ctnl, skb, nlh, &c);
+	}
 
 	err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
 	if (err < 0)
@@ -1881,9 +1885,11 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
 	int err;
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
-		return netlink_dump_start(ctnl, skb, nlh,
-					  ctnetlink_exp_dump_table,
-					  ctnetlink_exp_done, 0);
+		struct netlink_dump_control c = {
+			.dump = ctnetlink_exp_dump_table,
+			.done = ctnetlink_exp_done,
+		};
+		return netlink_dump_start(ctnl, skb, nlh, &c);
 	}
 
 	err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 11ba013..3eb348b 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -171,8 +171,10 @@ nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb,
 	char *acct_name;
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
-		return netlink_dump_start(nfnl, skb, nlh, nfnl_acct_dump,
-					  NULL, 0);
+		struct netlink_dump_control c = {
+			.dump = nfnl_acct_dump,
+		};
+		return netlink_dump_start(nfnl, skb, nlh, &c);
 	}
 
 	if (!tb[NFACCT_NAME])
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 4d751e3..ab74845 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1736,10 +1736,7 @@ errout_skb:
 
 int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 		       const struct nlmsghdr *nlh,
-		       int (*dump)(struct sk_buff *skb,
-				   struct netlink_callback *),
-		       int (*done)(struct netlink_callback *),
-		       u16 min_dump_alloc)
+		       struct netlink_dump_control *control)
 {
 	struct netlink_callback *cb;
 	struct sock *sk;
@@ -1750,10 +1747,10 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 	if (cb == NULL)
 		return -ENOBUFS;
 
-	cb->dump = dump;
-	cb->done = done;
+	cb->dump = control->dump;
+	cb->done = control->done;
 	cb->nlh = nlh;
-	cb->min_dump_alloc = min_dump_alloc;
+	cb->min_dump_alloc = control->min_dump_alloc;
 	atomic_inc(&skb->users);
 	cb->skb = skb;
 
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index a115471..9f40441 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -563,8 +563,13 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 			return -EOPNOTSUPP;
 
 		genl_unlock();
-		err = netlink_dump_start(net->genl_sock, skb, nlh,
-					 ops->dumpit, ops->done, 0);
+		{
+			struct netlink_dump_control c = {
+				.dump = ops->dumpit,
+				.done = ops->done,
+			};
+			err = netlink_dump_start(net->genl_sock, skb, nlh, &c);
+		}
 		genl_lock();
 		return err;
 	}
diff --git a/net/unix/diag.c b/net/unix/diag.c
index 6b7697f..4195555 100644
--- a/net/unix/diag.c
+++ b/net/unix/diag.c
@@ -301,10 +301,12 @@ static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
 	if (nlmsg_len(h) < hdrlen)
 		return -EINVAL;
 
-	if (h->nlmsg_flags & NLM_F_DUMP)
-		return netlink_dump_start(sock_diag_nlsk, skb, h,
-					  unix_diag_dump, NULL, 0);
-	else
+	if (h->nlmsg_flags & NLM_F_DUMP) {
+		struct netlink_dump_control c = {
+			.dump = unix_diag_dump,
+		};
+		return netlink_dump_start(sock_diag_nlsk, skb, h, &c);
+	} else
 		return unix_diag_get_exact(skb, h, (struct unix_diag_req *)NLMSG_DATA(h));
 }
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 66b84fb..7128dde 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2299,8 +2299,13 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 		if (link->dump == NULL)
 			return -EINVAL;
 
-		return netlink_dump_start(net->xfrm.nlsk, skb, nlh,
-					  link->dump, link->done, 0);
+		{
+			struct netlink_dump_control c = {
+				.dump = link->dump,
+				.done = link->done,
+			};
+			return netlink_dump_start(net->xfrm.nlsk, skb, nlh, &c);
+		}
 	}
 
 	err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] netlink: allow to pass data pointer to netlink_dump_start() callback
  2012-02-25  0:30 [PATCH 0/3] netlink: netlink_dump_start takes pointer to data pablo
  2012-02-25  0:30 ` [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start() pablo
@ 2012-02-25  0:30 ` pablo
  2012-02-26 19:27   ` David Miller
  2012-02-25  0:30 ` [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark pablo
  2 siblings, 1 reply; 10+ messages in thread
From: pablo @ 2012-02-25  0:30 UTC (permalink / raw)
  To: netdev; +Cc: netfilter-devel, davem

From: Pablo Neira Ayuso <pablo@netfilter.org>

This patch allows you to pass a data pointer that can be
accessed from the dump callback.

Netfilter is going to use this patch to provide filtered dumps
to user-space. This is specifically interesting in ctnetlink that
may handle lots of conntrack entries. We can save precious
cycles by skipping the conversion to TLV format of conntrack
entries that are not interesting for user-space.

More specifically, ctnetlink will include one operation to allow
to filter the dumping of conntrack entries by ctmark values.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netlink.h  |    2 ++
 net/netlink/af_netlink.c |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 1f8c1a9..a2092f5 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -225,6 +225,7 @@ struct netlink_callback {
 	int			(*dump)(struct sk_buff * skb,
 					struct netlink_callback *cb);
 	int			(*done)(struct netlink_callback *cb);
+	void			*data;
 	u16			family;
 	u16			min_dump_alloc;
 	unsigned int		prev_seq, seq;
@@ -251,6 +252,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
 struct netlink_dump_control {
 	int (*dump)(struct sk_buff *skb, struct netlink_callback *);
 	int (*done)(struct netlink_callback*);
+	void *data;
 	u16 min_dump_alloc;
 };
 
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index ab74845..32bb753 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1750,6 +1750,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 	cb->dump = control->dump;
 	cb->done = control->done;
 	cb->nlh = nlh;
+	cb->data = control->data;
 	cb->min_dump_alloc = control->min_dump_alloc;
 	atomic_inc(&skb->users);
 	cb->skb = skb;
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark
  2012-02-25  0:30 [PATCH 0/3] netlink: netlink_dump_start takes pointer to data pablo
  2012-02-25  0:30 ` [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start() pablo
  2012-02-25  0:30 ` [PATCH 2/3] netlink: allow to pass data pointer to netlink_dump_start() callback pablo
@ 2012-02-25  0:30 ` pablo
  2012-02-25  0:41   ` Pablo Neira Ayuso
  2 siblings, 1 reply; 10+ messages in thread
From: pablo @ 2012-02-25  0:30 UTC (permalink / raw)
  To: netdev; +Cc: netfilter-devel, davem

From: Pablo Neira Ayuso <pablo@netfilter.org>

This patch adds CTA_MARK_MASK which, together with CTA_MARK, allows
you to selectively send conntrack entries to user-space by
returning those that match mark & mask.

With this, we can save cycles in the building and the parsing of
the entries that may be later on filtered out in user-space by using
the ctmark & mask.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter/nfnetlink_conntrack.h |    1 +
 net/netfilter/nf_conntrack_netlink.c          |   32 +++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 5ec1abc..e58e4b9 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -43,6 +43,7 @@ enum ctattr_type {
 	CTA_ZONE,
 	CTA_SECCTX,
 	CTA_TIMESTAMP,
+	CTA_MARK_MASK,
 	__CTA_MAX
 };
 #define CTA_MAX (__CTA_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index dd4aaba..5874917 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -691,9 +691,18 @@ static int ctnetlink_done(struct netlink_callback *cb)
 {
 	if (cb->args[1])
 		nf_ct_put((struct nf_conn *)cb->args[1]);
+	if (cb->data)
+		kfree(cb->data);
 	return 0;
 }
 
+struct ctnetlink_dump_filter {
+	struct {
+		u_int32_t val;
+		u_int32_t mask;
+	} mark;
+};
+
 static int
 ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
@@ -703,6 +712,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 	struct hlist_nulls_node *n;
 	struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
 	u_int8_t l3proto = nfmsg->nfgen_family;
+	const struct ctnetlink_dump_filter *filter = cb->data;
 
 	spin_lock_bh(&nf_conntrack_lock);
 	last = (struct nf_conn *)cb->args[1];
@@ -723,6 +733,12 @@ restart:
 					continue;
 				cb->args[1] = 0;
 			}
+#ifdef CONFIG_NF_CONNTRACK_MARK
+			if (filter && !((ct->mark & filter->mark.mask) ==
+					filter->mark.val)) {
+				continue;
+			}
+#endif
 			if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
 						cb->nlh->nlmsg_seq,
 						NFNL_MSG_TYPE(
@@ -894,6 +910,7 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
 	[CTA_NAT_DST]		= { .type = NLA_NESTED },
 	[CTA_TUPLE_MASTER]	= { .type = NLA_NESTED },
 	[CTA_ZONE]		= { .type = NLA_U16 },
+	[CTA_MARK_MASK]		= { .type = NLA_U32 },
 };
 
 static int
@@ -982,6 +999,21 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
 			.dump = ctnetlink_dump_table,
 			.done = ctnetlink_done,
 		};
+#ifdef CONFIG_NF_CONNTRACK_MARK
+		if (cda[CTA_MARK] && cda[CTA_MARK_MASK]) {
+			struct ctnetlink_dump_filter *filter;
+
+			filter = kzalloc(sizeof(struct ctnetlink_dump_filter),
+					 GFP_ATOMIC);
+			if (filter == NULL)
+				return -ENOMEM;
+
+			filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
+			filter->mark.mask =
+				ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
+			c.data = filter;
+		}
+#endif
 		return netlink_dump_start(ctnl, skb, nlh, &c);
 	}
 
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark
  2012-02-25  0:30 ` [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark pablo
@ 2012-02-25  0:41   ` Pablo Neira Ayuso
  2012-02-26 19:27     ` David Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-25  0:41 UTC (permalink / raw)
  To: netdev; +Cc: netfilter-devel, davem

[-- Attachment #1: Type: text/plain, Size: 625 bytes --]

On Sat, Feb 25, 2012 at 01:30:17AM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> This patch adds CTA_MARK_MASK which, together with CTA_MARK, allows
> you to selectively send conntrack entries to user-space by
> returning those that match mark & mask.
> 
> With this, we can save cycles in the building and the parsing of
> the entries that may be later on filtered out in user-space by using
> the ctmark & mask.

Minor glitch in this patch. One ifdef was missing that would spot an
unused variable warning if CONFIG_NF_CONNTRACK_MARK is disabled.

New patch for ctnetlink attached.

[-- Attachment #2: 0003-netfilter-ctnetlink-support-kernel-space-dump-filter.patch --]
[-- Type: text/x-diff, Size: 3461 bytes --]

>From 604bb5f7385bcde5be0e0a5f3f52fa05ef21d3bc Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sat, 25 Feb 2012 00:48:38 +0100
Subject: [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump
 filtering by ctmark

This patch adds CTA_MARK_MASK which, together with CTA_MARK, allows
you to selectively send conntrack entries to user-space by
returning those that match mark & mask.

With this, we can save cycles in the building and the parsing of
the entries that may be later on filtered out in user-space by using
the ctmark & mask.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter/nfnetlink_conntrack.h |    1 +
 net/netfilter/nf_conntrack_netlink.c          |   35 ++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 5ec1abc..e58e4b9 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -43,6 +43,7 @@ enum ctattr_type {
 	CTA_ZONE,
 	CTA_SECCTX,
 	CTA_TIMESTAMP,
+	CTA_MARK_MASK,
 	__CTA_MAX
 };
 #define CTA_MAX (__CTA_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index dd4aaba..800ec17 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -691,9 +691,18 @@ static int ctnetlink_done(struct netlink_callback *cb)
 {
 	if (cb->args[1])
 		nf_ct_put((struct nf_conn *)cb->args[1]);
+	if (cb->data)
+		kfree(cb->data);
 	return 0;
 }
 
+struct ctnetlink_dump_filter {
+	struct {
+		u_int32_t val;
+		u_int32_t mask;
+	} mark;
+};
+
 static int
 ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
@@ -703,7 +712,9 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 	struct hlist_nulls_node *n;
 	struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
 	u_int8_t l3proto = nfmsg->nfgen_family;
-
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	const struct ctnetlink_dump_filter *filter = cb->data;
+#endif
 	spin_lock_bh(&nf_conntrack_lock);
 	last = (struct nf_conn *)cb->args[1];
 	for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) {
@@ -723,6 +734,12 @@ restart:
 					continue;
 				cb->args[1] = 0;
 			}
+#ifdef CONFIG_NF_CONNTRACK_MARK
+			if (filter && !((ct->mark & filter->mark.mask) ==
+					filter->mark.val)) {
+				continue;
+			}
+#endif
 			if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
 						cb->nlh->nlmsg_seq,
 						NFNL_MSG_TYPE(
@@ -894,6 +911,7 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
 	[CTA_NAT_DST]		= { .type = NLA_NESTED },
 	[CTA_TUPLE_MASTER]	= { .type = NLA_NESTED },
 	[CTA_ZONE]		= { .type = NLA_U16 },
+	[CTA_MARK_MASK]		= { .type = NLA_U32 },
 };
 
 static int
@@ -982,6 +1000,21 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
 			.dump = ctnetlink_dump_table,
 			.done = ctnetlink_done,
 		};
+#ifdef CONFIG_NF_CONNTRACK_MARK
+		if (cda[CTA_MARK] && cda[CTA_MARK_MASK]) {
+			struct ctnetlink_dump_filter *filter;
+
+			filter = kzalloc(sizeof(struct ctnetlink_dump_filter),
+					 GFP_ATOMIC);
+			if (filter == NULL)
+				return -ENOMEM;
+
+			filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
+			filter->mark.mask =
+				ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
+			c.data = filter;
+		}
+#endif
 		return netlink_dump_start(ctnl, skb, nlh, &c);
 	}
 
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start()
  2012-02-25  0:30 ` [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start() pablo
@ 2012-02-25  1:12   ` Jan Engelhardt
  2012-02-25 13:22     ` Pablo Neira Ayuso
  2012-02-26 19:26   ` David Miller
  1 sibling, 1 reply; 10+ messages in thread
From: Jan Engelhardt @ 2012-02-25  1:12 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, davem

On Saturday 2012-02-25 01:30, pablo@netfilter.org wrote:

>From: Pablo Neira Ayuso <pablo@netfilter.org>
>
>Davem considers that the argument list of this interface is getting
>out of control. This patch tries to address this issue following
>his proposal:
>
>struct netlink_dump_control c = { .dump = dump, .done = done, ... };
>
>netlink_dump_start(..., &c);

What about adding skb and nlh into c as well? After all, skb
is not nearly as much {used directly} as it is in Xtables.

>+		{
>+			struct netlink_dump_control c = {
>+				.dump = link->dump,
>+				.done = link->done,
>+			};
>+			return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
>+		}

You can also use

		return netlink_dump_start(crypto_nlsk, skb,
		       &(const struct netlink_dump_control)
		       {.dump = link->dump, .done = link->done}));

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start()
  2012-02-25  1:12   ` Jan Engelhardt
@ 2012-02-25 13:22     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 10+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-25 13:22 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netdev, netfilter-devel, davem

On Sat, Feb 25, 2012 at 02:12:22AM +0100, Jan Engelhardt wrote:
> On Saturday 2012-02-25 01:30, pablo@netfilter.org wrote:
> 
> >From: Pablo Neira Ayuso <pablo@netfilter.org>
> >
> >Davem considers that the argument list of this interface is getting
> >out of control. This patch tries to address this issue following
> >his proposal:
> >
> >struct netlink_dump_control c = { .dump = dump, .done = done, ... };
> >
> >netlink_dump_start(..., &c);
> 
> What about adding skb and nlh into c as well? After all, skb
> is not nearly as much {used directly} as it is in Xtables.

If you look at all netlink_dump_start invocations. Those are always
included. The idea was to add to the structure fields that may be
unset.

> >+		{
> >+			struct netlink_dump_control c = {
> >+				.dump = link->dump,
> >+				.done = link->done,
> >+			};
> >+			return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
> >+		}
> 
> You can also use
> 
> 		return netlink_dump_start(crypto_nlsk, skb,
> 		       &(const struct netlink_dump_control)
> 		       {.dump = link->dump, .done = link->done}));

Nice to know, thanks. Haven't see this in any other part of the kernel
code though and it looks a bit ugly IMO. I think I prefer the way it is
now.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start()
  2012-02-25  0:30 ` [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start() pablo
  2012-02-25  1:12   ` Jan Engelhardt
@ 2012-02-26 19:26   ` David Miller
  1 sibling, 0 replies; 10+ messages in thread
From: David Miller @ 2012-02-26 19:26 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel

From: pablo@netfilter.org
Date: Sat, 25 Feb 2012 01:30:15 +0100

> From: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> Davem considers that the argument list of this interface is getting
> out of control. This patch tries to address this issue following
> his proposal:
> 
> struct netlink_dump_control c = { .dump = dump, .done = done, ... };
> 
> netlink_dump_start(..., &c);
> 
> Suggested by David S. Miller.
> 
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Applied.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] netlink: allow to pass data pointer to netlink_dump_start() callback
  2012-02-25  0:30 ` [PATCH 2/3] netlink: allow to pass data pointer to netlink_dump_start() callback pablo
@ 2012-02-26 19:27   ` David Miller
  0 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2012-02-26 19:27 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel

From: pablo@netfilter.org
Date: Sat, 25 Feb 2012 01:30:16 +0100

> From: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> This patch allows you to pass a data pointer that can be
> accessed from the dump callback.
> 
> Netfilter is going to use this patch to provide filtered dumps
> to user-space. This is specifically interesting in ctnetlink that
> may handle lots of conntrack entries. We can save precious
> cycles by skipping the conversion to TLV format of conntrack
> entries that are not interesting for user-space.
> 
> More specifically, ctnetlink will include one operation to allow
> to filter the dumping of conntrack entries by ctmark values.
> 
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Applied.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark
  2012-02-25  0:41   ` Pablo Neira Ayuso
@ 2012-02-26 19:27     ` David Miller
  0 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2012-02-26 19:27 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sat, 25 Feb 2012 01:41:50 +0100

> On Sat, Feb 25, 2012 at 01:30:17AM +0100, pablo@netfilter.org wrote:
>> From: Pablo Neira Ayuso <pablo@netfilter.org>
>> 
>> This patch adds CTA_MARK_MASK which, together with CTA_MARK, allows
>> you to selectively send conntrack entries to user-space by
>> returning those that match mark & mask.
>> 
>> With this, we can save cycles in the building and the parsing of
>> the entries that may be later on filtered out in user-space by using
>> the ctmark & mask.
> 
> Minor glitch in this patch. One ifdef was missing that would spot an
> unused variable warning if CONFIG_NF_CONNTRACK_MARK is disabled.
> 
> New patch for ctnetlink attached.

Applied.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-02-26 19:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-25  0:30 [PATCH 0/3] netlink: netlink_dump_start takes pointer to data pablo
2012-02-25  0:30 ` [PATCH 1/3] netlink: add netlink_dump_control structure for netlink_dump_start() pablo
2012-02-25  1:12   ` Jan Engelhardt
2012-02-25 13:22     ` Pablo Neira Ayuso
2012-02-26 19:26   ` David Miller
2012-02-25  0:30 ` [PATCH 2/3] netlink: allow to pass data pointer to netlink_dump_start() callback pablo
2012-02-26 19:27   ` David Miller
2012-02-25  0:30 ` [PATCH 3/3] netfilter: ctnetlink: support kernel-space dump filtering by ctmark pablo
2012-02-25  0:41   ` Pablo Neira Ayuso
2012-02-26 19:27     ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).