From patchwork Wed Aug 20 18:03:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Perevalov X-Patchwork-Id: 381755 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 5001214009C for ; Thu, 21 Aug 2014 04:03:25 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752509AbaHTSDY (ORCPT ); Wed, 20 Aug 2014 14:03:24 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:22612 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752010AbaHTSDX (ORCPT ); Wed, 20 Aug 2014 14:03:23 -0400 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NAM006SAAAE2K80@mailout2.w1.samsung.com> for netfilter-devel@vger.kernel.org; Wed, 20 Aug 2014 19:06:14 +0100 (BST) X-AuditID: cbfec7f5-b7f776d000003e54-07-53f4e2e941e1 Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 6D.E4.15956.9E2E4F35; Wed, 20 Aug 2014 19:03:21 +0100 (BST) Received: from auperevalov-R560.rnd.samsung.ru ([106.109.9.219]) by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NAM00F1YA5KAF00@eusync3.samsung.com>; Wed, 20 Aug 2014 19:03:21 +0100 (BST) From: Alexey Perevalov To: pablo@netfilter.org Cc: Alexey Perevalov , alexey.perevalov@hotmail.com, mathieu.poirier@linaro.org, netfilter-devel@vger.kernel.org, kyungmin.park@samsung.com, hs81.go@samsung.com Subject: [[PATCH v3]] netfilter: nfnetlink_acct: add filter support to nfacct counter list/reset Date: Wed, 20 Aug 2014 22:03:18 +0400 Message-id: <1408557798-6455-1-git-send-email-a.perevalov@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <20140820133401.GA7422@salvia> References: <20140820133401.GA7422@salvia> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrMJMWRmVeSWpSXmKPExsVy+t/xq7ovH30JNth2mc1i7t3zLBbv515l sbi/+iSbxdmmN+wWW/ccYLKYsO4Ui8X0N1eZHdg9HvecYfO4c20Pm8fb3yeYPPq2rGL0+LxJ LoA1issmJTUnsyy1SN8ugStj87tt7AX3lSpmHe1ka2Bskuli5OSQEDCReDjjMyOELSZx4d56 ti5GLg4hgaWMEnOWnGQFSQgJTGWS+HvDqIuRg4NNwEBi3z1bkLCIgLjEoQ2dLCD1zAJ7GSV2 T5/GDJIQFkiS2DLhGBuIzSKgKvF47zdGkF5eATeJxxvKQUwJAQWJOZNsQCo4BbQlTk/8wQKx SUvixbq3rBMYeRcwMqxiFE0tTS4oTkrPNdIrTswtLs1L10vOz93ECAmorzsYlx6zOsQowMGo xMN7c9GXYCHWxLLiytxDjBIczEoivPXXgEK8KYmVValF+fFFpTmpxYcYmTg4pRoY568u4/96 9dPle3y8WhMXHnu0fK1Sk9vrSS0FvwU+7TTdEBn4tXKujs58XvvFrz7M/rlhlsGUpxfj1ELU BFdcMtjUuGyPrMV6Z7Mi3chPYp5HFFonT9HVjZkVoX8nKlZ0yco7ubczDZ54bJF1U7r06FoF +2TfD+euLo7kyf4qN10iok6RJeDlGSWW4oxEQy3mouJEACurl9AGAgAA Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Filtering covers following cases: 1. no filter specified. In this case client will get old behaviour 2. filter specified for getting only counters: in this case marks should be NFACCT_F_QUOTAS and value 0 3. filter specified for getting quotas: for packet based quota mask should be NFACCT_F_QUOTA_PKTS and value - the same, for byte based quota mask should be NFACCT_F_QUOTA_BYTES and value - the same. Bit set for quota is't supported in this patch. NFACCT_F_QUOTA didn't expose for user space program in public header as well. In case of NFACCT_F_QUOTA two request is necessary, one for NFACCT_F_QUOTA_PKTS and another one for NFACCT_F_QUOTA_BYTES. Signed-off-by: Alexey Perevalov --- include/uapi/linux/netfilter/nfnetlink_acct.h | 8 ++++ net/netfilter/nfnetlink_acct.c | 51 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/uapi/linux/netfilter/nfnetlink_acct.h b/include/uapi/linux/netfilter/nfnetlink_acct.h index 51404ec..f3e34db 100644 --- a/include/uapi/linux/netfilter/nfnetlink_acct.h +++ b/include/uapi/linux/netfilter/nfnetlink_acct.h @@ -28,9 +28,17 @@ enum nfnl_acct_type { NFACCT_USE, NFACCT_FLAGS, NFACCT_QUOTA, + NFACCT_FILTER, __NFACCT_MAX }; #define NFACCT_MAX (__NFACCT_MAX - 1) +enum nfnl_attr_filter_type { + NFACCT_FILTER_UNSPEC, + NFACCT_FILTER_MASK, + NFACCT_FILTER_VALUE, + __NFACCT_FILTER_MAX +}; +#define NFACCT_FILTER_MAX (__NFACCT_FILTER_MAX - 1) #endif /* _UAPI_NFNL_ACCT_H_ */ diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 3ea0eac..0f7159f 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c @@ -40,6 +40,11 @@ struct nf_acct { char data[0]; }; +struct nfacct_filter { + u32 value; + u32 mask; +}; + #define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES) #define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */ @@ -181,6 +186,7 @@ static int nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct nf_acct *cur, *last; + const struct nfacct_filter *filter = cb->data; if (cb->args[2]) return 0; @@ -197,6 +203,10 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) last = NULL; } + + if (filter && (cur->flags & filter->mask) != filter->value) + continue; + if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NFNL_MSG_TYPE(cb->nlh->nlmsg_type), @@ -212,6 +222,32 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) } static int +nfnl_acct_done(struct netlink_callback *cb) +{ + kfree(cb->data); + return 0; +} + +static const struct nla_policy filter_policy[NFACCT_FILTER_MAX + 1] = { + [NFACCT_FILTER_MASK] = { .type = NLA_U32 }, + [NFACCT_FILTER_VALUE] = { .type = NLA_U32 }, +}; + +static struct nfacct_filter * +nfacct_filter_alloc(struct nlattr *attrs[NFACCT_FILTER_MAX + 1]) +{ + struct nfacct_filter *filter = kzalloc(sizeof(struct nfacct_filter), + GFP_KERNEL); + if (!filter) + return ERR_PTR(-ENOMEM); + + filter->mask = nla_get_be32(attrs[NFACCT_FILTER_MASK]); + filter->value = nla_get_be32(attrs[NFACCT_FILTER_VALUE]); + + return filter; +} + +static int nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const tb[]) { @@ -222,7 +258,21 @@ nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb, if (nlh->nlmsg_flags & NLM_F_DUMP) { struct netlink_dump_control c = { .dump = nfnl_acct_dump, + .done = nfnl_acct_done, }; + if (tb[NFACCT_FILTER]) { + struct nlattr *attrs[NFACCT_FILTER_MAX + 1]; + ret = nla_parse_nested(attrs, NFACCT_FILTER_MAX, + tb[NFACCT_FILTER], + filter_policy); + if (ret < 0) + return ret; + + c.data = nfacct_filter_alloc(attrs); + if (IS_ERR(c.data)) + return PTR_ERR(c.data); + } + return netlink_dump_start(nfnl, skb, nlh, &c); } @@ -314,6 +364,7 @@ static const struct nla_policy nfnl_acct_policy[NFACCT_MAX+1] = { [NFACCT_PKTS] = { .type = NLA_U64 }, [NFACCT_FLAGS] = { .type = NLA_U32 }, [NFACCT_QUOTA] = { .type = NLA_U64 }, + [NFACCT_FILTER] = {.type = NLA_NESTED }, }; static const struct nfnl_callback nfnl_acct_cb[NFNL_MSG_ACCT_MAX] = {