Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b2d8a7b authored by Patrick McHardy's avatar Patrick McHardy Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_tables: add helper functions for expression handling



Add helper functions for initializing, cloning, dumping and destroying
a single expression that is not part of a rule.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 24477e57
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
#ifndef _NET_NF_TABLES_H
#ifndef _NET_NF_TABLES_H
#define _NET_NF_TABLES_H
#define _NET_NF_TABLES_H


#include <linux/module.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/netfilter.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink.h>
@@ -641,6 +642,18 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
	return (void *)expr->data;
	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
 *	struct nft_rule - nf_tables rule
 *
 *
+51 −5
Original line number Original line Diff line number Diff line
@@ -1545,6 +1545,23 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
	return -1;
	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 {
struct nft_expr_info {
	const struct nft_expr_ops	*ops;
	const struct nft_expr_ops	*ops;
	struct nlattr			*tb[NFT_EXPR_MAXATTR + 1];
	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);
	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
 * Rules
 */
 */
@@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
	if (list == NULL)
	if (list == NULL)
		goto nla_put_failure;
		goto nla_put_failure;
	nft_rule_for_each_expr(expr, next, rule) {
	nft_rule_for_each_expr(expr, next, rule) {
		struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM);
		if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
		if (elem == NULL)
			goto nla_put_failure;
		if (nf_tables_fill_expr_info(skb, expr) < 0)
			goto nla_put_failure;
			goto nla_put_failure;
		nla_nest_end(skb, elem);
	}
	}
	nla_nest_end(skb, list);
	nla_nest_end(skb, list);