{"id":805163,"url":"http://patchwork.ozlabs.org/api/1.2/patches/805163/?format=json","web_url":"http://patchwork.ozlabs.org/project/netfilter-devel/patch/20170823204125.31427-1-pablombg@gmail.com/","project":{"id":26,"url":"http://patchwork.ozlabs.org/api/1.2/projects/26/?format=json","name":"Netfilter Development","link_name":"netfilter-devel","list_id":"netfilter-devel.vger.kernel.org","list_email":"netfilter-devel@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20170823204125.31427-1-pablombg@gmail.com>","list_archive_url":null,"date":"2017-08-23T20:41:23","name":"[nf-next,1/3] netfilter: nf_tables: add select_ops for stateful objects","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"c98b855fd395bfb94cc8a2c8bf81092d0562e5e6","submitter":{"id":67698,"url":"http://patchwork.ozlabs.org/api/1.2/people/67698/?format=json","name":"Pablo M. Bermudo Garay","email":"pablombg@gmail.com"},"delegate":{"id":6139,"url":"http://patchwork.ozlabs.org/api/1.2/users/6139/?format=json","username":"pablo","first_name":"Pablo","last_name":"Neira","email":"pablo@netfilter.org"},"mbox":"http://patchwork.ozlabs.org/project/netfilter-devel/patch/20170823204125.31427-1-pablombg@gmail.com/mbox/","series":[],"comments":"http://patchwork.ozlabs.org/api/patches/805163/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/805163/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netfilter-devel-owner@vger.kernel.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netfilter-devel-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"B9YTrI4e\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xczr93xKcz9t34\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 24 Aug 2017 06:42:17 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754160AbdHWUmQ (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tWed, 23 Aug 2017 16:42:16 -0400","from mail-wm0-f67.google.com ([74.125.82.67]:35903 \"EHLO\n\tmail-wm0-f67.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751728AbdHWUmP (ORCPT\n\t<rfc822;netfilter-devel@vger.kernel.org>);\n\tWed, 23 Aug 2017 16:42:15 -0400","by mail-wm0-f67.google.com with SMTP id f127so702214wmf.3\n\tfor <netfilter-devel@vger.kernel.org>;\n\tWed, 23 Aug 2017 13:42:15 -0700 (PDT)","from localhost.localdomain (75.red-88-9-82.dynamicip.rima-tde.net.\n\t[88.9.82.75]) by smtp.gmail.com with ESMTPSA id\n\t65sm2035727wmf.0.2017.08.23.13.42.11\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 23 Aug 2017 13:42:12 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id;\n\tbh=VPnF0gSIFw0s8sy2do9AzhH39DKplAy8jJ3nlbrvwr0=;\n\tb=B9YTrI4eEVjcznHC3KnsJbsQrQuH9FdGOAOHT/O8oalLzH0EDKy7tw4NX/1Sa5uV/y\n\tC2n3i4liak09i23kOxcddu9s3PKjEWbHLlp/s2sOAHNXq4Im8u6DfgQHFkaFtjNcj/+d\n\tqXx5NGaS0Dha177p1HgsD34WueOmBcOCjasvBtzYt7JYyiDoSjt0KfxBfCAWsOYJ1t8K\n\tL45YaEvN5wC5ChRDjvlrpap8aDSD6JLrpAo1lfBgTaJSYNHcXljxBK36My8jCDjbyn9h\n\t9lspJebBqjypJHwmtIXd1Lhrxko+aGqcVAvv+7cpdPZLnvaibT//aHaJ2RsN5ubcfvU/\n\tjCDQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id;\n\tbh=VPnF0gSIFw0s8sy2do9AzhH39DKplAy8jJ3nlbrvwr0=;\n\tb=Z5jWuPgh3NDwhzZkVIBkp+0wuzOFr/GI8iLsQgZLMzdUpNdlpwffW/JDaHD/ctrLNt\n\tGVz2+QZHdF+4/yw264Yw8HdfZA4T8FMe7msxdT4sBHXNflgleKLZZxoBAUqXbLVuwTn9\n\t/a4Eth8uRWY0zeP+o+O1JMMQWA8LTSyoRAOvT0SOUgKpYQunauG563yqRZu+RMpFrFRE\n\tHcmOdXwo9Gr0w645rLEm6ENSQc8tf7qN7Hrgqm5cn9fsC6tY7/G0NExpE2AJ4nqj1Wqq\n\te55P/tRbn/eQ/aVq9EWcYysWWK2GCWfRhyks/k1kIDWqQ9n59OPzjVSSevyoZYiP31Ll\n\tH27A==","X-Gm-Message-State":"AHYfb5hLFQJAJDuIuZGhKs4JKpb4eu/BmBxbweQPBBJwGAkXCGGskxNj\n\t5/SoFIttN/CEqkx8lO8=","X-Received":"by 10.28.181.143 with SMTP id e137mr2939566wmf.68.1503520934111; \n\tWed, 23 Aug 2017 13:42:14 -0700 (PDT)","From":"\"Pablo M. Bermudo Garay\" <pablombg@gmail.com>","To":"netfilter-devel@vger.kernel.org","Cc":"pablo@netfilter.org, \"Pablo M. Bermudo Garay\" <pablombg@gmail.com>","Subject":"[PATCH nf-next 1/3] netfilter: nf_tables: add select_ops for\n\tstateful objects","Date":"Wed, 23 Aug 2017 22:41:23 +0200","Message-Id":"<20170823204125.31427-1-pablombg@gmail.com>","X-Mailer":"git-send-email 2.14.1","Sender":"netfilter-devel-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netfilter-devel.vger.kernel.org>","X-Mailing-List":"netfilter-devel@vger.kernel.org"},"content":"This patch adds support for overloading stateful objects operations\nthrough the select_ops() callback, just as it is implemented for\nexpressions.\n\nThis change is needed for upcoming additions to the stateful objects\ninfrastructure.\n\nSigned-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com>\n---\n include/net/netfilter/nf_tables.h | 30 ++++++++++++++++++++++--------\n net/netfilter/nf_tables_api.c     | 27 ++++++++++++++++++++-------\n net/netfilter/nft_counter.c       | 12 ++++++++----\n net/netfilter/nft_ct.c            | 12 ++++++++----\n net/netfilter/nft_objref.c        |  4 ++--\n net/netfilter/nft_quota.c         | 12 ++++++++----\n 6 files changed, 68 insertions(+), 29 deletions(-)","diff":"diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h\nindex f9795fe394f3..b53639af1c7b 100644\n--- a/include/net/netfilter/nf_tables.h\n+++ b/include/net/netfilter/nf_tables.h\n@@ -1008,6 +1008,7 @@ int nft_verdict_dump(struct sk_buff *skb, int type,\n  *\t@list: table stateful object list node\n  *\t@table: table this object belongs to\n  *\t@type: pointer to object type\n+ *\t@ops: object operations\n  *\t@data: pointer to object data\n  *\t@name: name of this stateful object\n  *\t@genmask: generation mask\n@@ -1022,6 +1023,7 @@ struct nft_object {\n \t\t\t\t\tuse:30;\n \t/* runtime data below here */\n \tconst struct nft_object_type\t*type ____cacheline_aligned;\n+\tconst struct nft_object_ops\t*ops;\n \tunsigned char\t\t\tdata[]\n \t\t__attribute__((aligned(__alignof__(u64))));\n };\n@@ -1044,27 +1046,39 @@ void nft_obj_notify(struct net *net, struct nft_table *table,\n /**\n  *\tstruct nft_object_type - stateful object type\n  *\n- *\t@eval: stateful object evaluation function\n+ *\t@select_ops: function to select nft_object_ops\n+ *\t@ops: default ops, used when no select_ops functions is present\n  *\t@list: list node in list of object types\n  *\t@type: stateful object numeric type\n- *\t@size: stateful object size\n  *\t@owner: module owner\n  *\t@maxattr: maximum netlink attribute\n  *\t@policy: netlink attribute policy\n+ */\n+struct nft_object_type {\n+\tconst struct nft_object_ops\t*(*select_ops)(const struct nft_ctx *,\n+\t\t\t\t\t\t       const struct nlattr * const tb[]);\n+\tconst struct nft_object_ops\t*ops;\n+\tstruct list_head\t\tlist;\n+\tu32\t\t\t\ttype;\n+\tunsigned int                    maxattr;\n+\tstruct module\t\t\t*owner;\n+\tconst struct nla_policy\t\t*policy;\n+};\n+\n+/**\n+ *\tstruct nft_object_ops - stateful object operations\n+ *\n+ *\t@eval: stateful object evaluation function\n+ *\t@size: stateful object size\n  *\t@init: initialize object from netlink attributes\n  *\t@destroy: release existing stateful object\n  *\t@dump: netlink dump stateful object\n  */\n-struct nft_object_type {\n+struct nft_object_ops {\n \tvoid\t\t\t\t(*eval)(struct nft_object *obj,\n \t\t\t\t\t\tstruct nft_regs *regs,\n \t\t\t\t\t\tconst struct nft_pktinfo *pkt);\n-\tstruct list_head\t\tlist;\n-\tu32\t\t\t\ttype;\n \tunsigned int\t\t\tsize;\n-\tunsigned int\t\t\tmaxattr;\n-\tstruct module\t\t\t*owner;\n-\tconst struct nla_policy\t\t*policy;\n \tint\t\t\t\t(*init)(const struct nft_ctx *ctx,\n \t\t\t\t\t\tconst struct nlattr *const tb[],\n \t\t\t\t\t\tstruct nft_object *obj);\ndiff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c\nindex 149785ff1c7b..b946774707b1 100644\n--- a/net/netfilter/nf_tables_api.c\n+++ b/net/netfilter/nf_tables_api.c\n@@ -4270,6 +4270,7 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,\n \t\t\t\t       const struct nlattr *attr)\n {\n \tstruct nlattr *tb[type->maxattr + 1];\n+\tconst struct nft_object_ops *ops;\n \tstruct nft_object *obj;\n \tint err;\n \n@@ -4282,12 +4283,24 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,\n \t\tmemset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));\n \t}\n \n+\tif (type->select_ops) {\n+\t\tops = type->select_ops(ctx, (const struct nlattr * const *)tb);\n+\t\tif (IS_ERR(ops)) {\n+\t\t\terr = PTR_ERR(ops);\n+\t\t\tgoto err1;\n+\t\t}\n+\t} else {\n+\t\tops = type->ops;\n+\t}\n+\n \terr = -ENOMEM;\n-\tobj = kzalloc(sizeof(struct nft_object) + type->size, GFP_KERNEL);\n+\tobj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL);\n \tif (obj == NULL)\n \t\tgoto err1;\n \n-\terr = type->init(ctx, (const struct nlattr * const *)tb, obj);\n+\tobj->ops = ops;\n+\n+\terr = ops->init(ctx, (const struct nlattr * const *)tb, obj);\n \tif (err < 0)\n \t\tgoto err2;\n \n@@ -4307,7 +4320,7 @@ static int nft_object_dump(struct sk_buff *skb, unsigned int attr,\n \tnest = nla_nest_start(skb, attr);\n \tif (!nest)\n \t\tgoto nla_put_failure;\n-\tif (obj->type->dump(skb, obj, reset) < 0)\n+\tif (obj->ops->dump(skb, obj, reset) < 0)\n \t\tgoto nla_put_failure;\n \tnla_nest_end(skb, nest);\n \treturn 0;\n@@ -4418,8 +4431,8 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,\n err3:\n \tkfree(obj->name);\n err2:\n-\tif (obj->type->destroy)\n-\t\tobj->type->destroy(obj);\n+\tif (obj->ops->destroy)\n+\t\tobj->ops->destroy(obj);\n \tkfree(obj);\n err1:\n \tmodule_put(type->owner);\n@@ -4628,8 +4641,8 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,\n \n static void nft_obj_destroy(struct nft_object *obj)\n {\n-\tif (obj->type->destroy)\n-\t\tobj->type->destroy(obj);\n+\tif (obj->ops->destroy)\n+\t\tobj->ops->destroy(obj);\n \n \tmodule_put(obj->type->owner);\n \tkfree(obj->name);\ndiff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c\nindex 67a710ebde09..5ae8ae2a879e 100644\n--- a/net/netfilter/nft_counter.c\n+++ b/net/netfilter/nft_counter.c\n@@ -175,15 +175,19 @@ static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {\n \t[NFTA_COUNTER_BYTES]\t= { .type = NLA_U64 },\n };\n \n-static struct nft_object_type nft_counter_obj __read_mostly = {\n-\t.type\t\t= NFT_OBJECT_COUNTER,\n+static const struct nft_object_ops nft_counter_obj_ops = {\n \t.size\t\t= sizeof(struct nft_counter_percpu_priv),\n-\t.maxattr\t= NFTA_COUNTER_MAX,\n-\t.policy\t\t= nft_counter_policy,\n \t.eval\t\t= nft_counter_obj_eval,\n \t.init\t\t= nft_counter_obj_init,\n \t.destroy\t= nft_counter_obj_destroy,\n \t.dump\t\t= nft_counter_obj_dump,\n+};\n+\n+static struct nft_object_type nft_counter_obj __read_mostly = {\n+\t.type\t\t= NFT_OBJECT_COUNTER,\n+\t.ops\t\t= &nft_counter_obj_ops,\n+\t.maxattr\t= NFTA_COUNTER_MAX,\n+\t.policy\t\t= nft_counter_policy,\n \t.owner\t\t= THIS_MODULE,\n };\n \ndiff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c\nindex 1678e9e75e8e..39f10a0ede81 100644\n--- a/net/netfilter/nft_ct.c\n+++ b/net/netfilter/nft_ct.c\n@@ -904,15 +904,19 @@ static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = {\n \t[NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 },\n };\n \n-static struct nft_object_type nft_ct_helper_obj __read_mostly = {\n-\t.type\t\t= NFT_OBJECT_CT_HELPER,\n+static const struct nft_object_ops nft_ct_helper_obj_ops = {\n \t.size\t\t= sizeof(struct nft_ct_helper_obj),\n-\t.maxattr\t= NFTA_CT_HELPER_MAX,\n-\t.policy\t\t= nft_ct_helper_policy,\n \t.eval\t\t= nft_ct_helper_obj_eval,\n \t.init\t\t= nft_ct_helper_obj_init,\n \t.destroy\t= nft_ct_helper_obj_destroy,\n \t.dump\t\t= nft_ct_helper_obj_dump,\n+};\n+\n+static struct nft_object_type nft_ct_helper_obj __read_mostly = {\n+\t.type\t\t= NFT_OBJECT_CT_HELPER,\n+\t.ops\t\t= &nft_ct_helper_obj_ops,\n+\t.maxattr\t= NFTA_CT_HELPER_MAX,\n+\t.policy\t\t= nft_ct_helper_policy,\n \t.owner\t\t= THIS_MODULE,\n };\n \ndiff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c\nindex 1dd428fbaaa3..096468280a1e 100644\n--- a/net/netfilter/nft_objref.c\n+++ b/net/netfilter/nft_objref.c\n@@ -22,7 +22,7 @@ static void nft_objref_eval(const struct nft_expr *expr,\n {\n \tstruct nft_object *obj = nft_objref_priv(expr);\n \n-\tobj->type->eval(obj, regs, pkt);\n+\tobj->ops->eval(obj, regs, pkt);\n }\n \n static int nft_objref_init(const struct nft_ctx *ctx,\n@@ -104,7 +104,7 @@ static void nft_objref_map_eval(const struct nft_expr *expr,\n \t\treturn;\n \t}\n \tobj = *nft_set_ext_obj(ext);\n-\tobj->type->eval(obj, regs, pkt);\n+\tobj->ops->eval(obj, regs, pkt);\n }\n \n static int nft_objref_map_init(const struct nft_ctx *ctx,\ndiff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c\nindex 25e33159be57..f63c1797b8bc 100644\n--- a/net/netfilter/nft_quota.c\n+++ b/net/netfilter/nft_quota.c\n@@ -151,14 +151,18 @@ static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj,\n \treturn nft_quota_do_dump(skb, priv, reset);\n }\n \n-static struct nft_object_type nft_quota_obj __read_mostly = {\n-\t.type\t\t= NFT_OBJECT_QUOTA,\n+static const struct nft_object_ops nft_quota_obj_ops = {\n \t.size\t\t= sizeof(struct nft_quota),\n-\t.maxattr\t= NFTA_QUOTA_MAX,\n-\t.policy\t\t= nft_quota_policy,\n \t.init\t\t= nft_quota_obj_init,\n \t.eval\t\t= nft_quota_obj_eval,\n \t.dump\t\t= nft_quota_obj_dump,\n+};\n+\n+static struct nft_object_type nft_quota_obj __read_mostly = {\n+\t.type\t\t= NFT_OBJECT_QUOTA,\n+\t.ops\t\t= &nft_quota_obj_ops,\n+\t.maxattr\t= NFTA_QUOTA_MAX,\n+\t.policy\t\t= nft_quota_policy,\n \t.owner\t\t= THIS_MODULE,\n };\n \n","prefixes":["nf-next","1/3"]}