[PATCH nf-next,v1 01/12] netfilter: nf_tables: add nft_expr_info_setup() helper function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add helper function to allocate and set up nft_expr_info structure,
which contains the expression array.

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 net/netfilter/nf_tables_api.c | 90 ++++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 29 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 09542951656c..bbdf22646745 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -386,6 +386,60 @@ static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
 	}
 }
 
+struct nft_expr_info {
+	const struct nft_expr_ops	*ops;
+	const struct nlattr		*attr;
+	struct nlattr			*tb[NFT_EXPR_MAXATTR + 1];
+};
+
+static int nf_tables_expr_parse(const struct nft_ctx *ctx,
+				const struct nlattr *nla,
+				struct nft_expr_info *info);
+
+#define NFT_RULE_MAXEXPRS	128
+
+static struct nft_expr_info *
+nft_expr_info_setup(struct nft_ctx *ctx, const struct nlattr *nla,
+		    unsigned int *psize, unsigned int *pnum,
+		    struct netlink_ext_ack *extack)
+{
+	struct nft_expr_info *expr_info;
+	unsigned int n = 0, size = 0;
+	struct nlattr *tmp;
+	int err, rem;
+
+	expr_info = kvmalloc_array(NFT_RULE_MAXEXPRS,
+				   sizeof(struct nft_expr_info), GFP_KERNEL);
+	if (!expr_info)
+		return ERR_PTR(-ENOMEM);
+
+	nla_for_each_nested(tmp, nla, rem) {
+		err = -EINVAL;
+		if (nla_type(tmp) != NFTA_LIST_ELEM)
+			goto err_release_expr;
+
+		if (n == NFT_RULE_MAXEXPRS)
+			goto err_release_expr;
+
+		err = nf_tables_expr_parse(ctx, tmp, &expr_info[n]);
+		if (err < 0) {
+			NL_SET_BAD_ATTR(extack, tmp);
+			goto err_release_expr;
+		}
+		size += expr_info[n].ops->size;
+		n++;
+	}
+	*psize = size;
+	*pnum = n;
+
+	return expr_info;
+
+err_release_expr:
+	kvfree(expr_info);
+
+	return ERR_PTR(err);
+}
+
 static int
 nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
 {
@@ -2932,12 +2986,6 @@ int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
 	return -1;
 }
 
-struct nft_expr_info {
-	const struct nft_expr_ops	*ops;
-	const struct nlattr		*attr;
-	struct nlattr			*tb[NFT_EXPR_MAXATTR + 1];
-};
-
 static int nf_tables_expr_parse(const struct nft_ctx *ctx,
 				const struct nlattr *nla,
 				struct nft_expr_info *info)
@@ -3624,8 +3672,6 @@ static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
 					     const struct nft_chain *chain,
 					     const struct nlattr *nla);
 
-#define NFT_RULE_MAXEXPRS	128
-
 static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
 			     const struct nlattr * const nla[])
 {
@@ -3645,8 +3691,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
 	u64 handle, pos_handle;
 	struct nft_expr *expr;
 	struct nft_ctx ctx;
-	struct nlattr *tmp;
-	int err, rem;
+	int err;
 
 	lockdep_assert_held(&nft_net->commit_mutex);
 
@@ -3723,25 +3768,12 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
 	n = 0;
 	size = 0;
 	if (nla[NFTA_RULE_EXPRESSIONS]) {
-		expr_info = kvmalloc_array(NFT_RULE_MAXEXPRS,
-					   sizeof(struct nft_expr_info),
-					   GFP_KERNEL);
-		if (!expr_info)
-			return -ENOMEM;
-
-		nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
-			err = -EINVAL;
-			if (nla_type(tmp) != NFTA_LIST_ELEM)
-				goto err_release_expr;
-			if (n == NFT_RULE_MAXEXPRS)
-				goto err_release_expr;
-			err = nf_tables_expr_parse(&ctx, tmp, &expr_info[n]);
-			if (err < 0) {
-				NL_SET_BAD_ATTR(extack, tmp);
-				goto err_release_expr;
-			}
-			size += expr_info[n].ops->size;
-			n++;
+		expr_info = nft_expr_info_setup(&ctx,
+						nla[NFTA_RULE_EXPRESSIONS],
+						&size, &n, extack);
+		if (IS_ERR(expr_info)) {
+			err = PTR_ERR(expr_info);
+			goto err_release_expr;
 		}
 	}
 	/* Check for overflow of dlen field */
-- 
2.30.2




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux