From mboxrd@z Thu Jan 1 00:00:00 1970 From: Patrick McHardy Subject: [PATCH 1/5] netfilter: nf_tables: add helper functions for expression handling Date: Sat, 11 Apr 2015 10:46:38 +0100 Message-ID: <1428745602-31799-2-git-send-email-kaber@trash.net> References: <1428745602-31799-1-git-send-email-kaber@trash.net> Cc: netfilter-devel@vger.kernel.org To: pablo@netfilter.org Return-path: Received: from stinky.trash.net ([213.144.137.162]:49249 "EHLO stinky.trash.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752433AbbDKJqq (ORCPT ); Sat, 11 Apr 2015 05:46:46 -0400 In-Reply-To: <1428745602-31799-1-git-send-email-kaber@trash.net> Sender: netfilter-devel-owner@vger.kernel.org List-ID: Add helper functions for initializing, cloning, dumping and destroying a single expression that is not part of a rule. Signed-off-by: Patrick McHardy --- include/net/netfilter/nf_tables.h | 13 +++++++++ net/netfilter/nf_tables_api.c | 56 +++++++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index cb42da1..e21623c 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1,6 +1,7 @@ #ifndef _NET_NF_TABLES_H #define _NET_NF_TABLES_H +#include #include #include #include @@ -641,6 +642,18 @@ static inline void *nft_expr_priv(const struct nft_expr *expr) return (void *)expr->data; } +struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, + const struct nlattr *nla); +void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr); +int nft_expr_dump(struct sk_buff *skb, unsigned int attr, + const struct nft_expr *expr); + +static inline void nft_expr_clone(struct nft_expr *dst, struct nft_expr *src) +{ + __module_get(src->ops->type->owner); + memcpy(dst, src, src->ops->size); +} + /** * struct nft_rule - nf_tables rule * diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index ed0e70e..e97bee5 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1545,6 +1545,23 @@ nla_put_failure: return -1; }; +int nft_expr_dump(struct sk_buff *skb, unsigned int attr, + const struct nft_expr *expr) +{ + struct nlattr *nest; + + nest = nla_nest_start(skb, attr); + if (!nest) + goto nla_put_failure; + if (nf_tables_fill_expr_info(skb, expr) < 0) + goto nla_put_failure; + nla_nest_end(skb, nest); + return 0; + +nla_put_failure: + return -1; +} + struct nft_expr_info { const struct nft_expr_ops *ops; struct nlattr *tb[NFT_EXPR_MAXATTR + 1]; @@ -1622,6 +1639,39 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx, module_put(expr->ops->type->owner); } +struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, + const struct nlattr *nla) +{ + struct nft_expr_info info; + struct nft_expr *expr; + int err; + + err = nf_tables_expr_parse(ctx, nla, &info); + if (err < 0) + goto err1; + + err = -ENOMEM; + expr = kzalloc(info.ops->size, GFP_KERNEL); + if (expr == NULL) + goto err2; + + err = nf_tables_newexpr(ctx, &info, expr); + if (err < 0) + goto err2; + + return expr; +err2: + module_put(info.ops->type->owner); +err1: + return ERR_PTR(err); +} + +void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr) +{ + nf_tables_expr_destroy(ctx, expr); + kfree(expr); +} + /* * Rules */ @@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, if (list == NULL) goto nla_put_failure; nft_rule_for_each_expr(expr, next, rule) { - struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM); - if (elem == NULL) - goto nla_put_failure; - if (nf_tables_fill_expr_info(skb, expr) < 0) + if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0) goto nla_put_failure; - nla_nest_end(skb, elem); } nla_nest_end(skb, list); -- 2.1.0