Skip to content

Commit

Permalink
netfilter: nf_tables: add helper functions for expression handling
Browse files Browse the repository at this point in the history
Add helper functions for initializing, cloning, dumping and destroying
a single expression that is not part of a rule.

Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
  • Loading branch information
kaber authored and ummakynes committed Apr 13, 2015
1 parent 24477e5 commit 0b2d8a7
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 5 deletions.
13 changes: 13 additions & 0 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _NET_NF_TABLES_H
#define _NET_NF_TABLES_H

#include <linux/module.h>
#include <linux/list.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
Expand Down Expand Up @@ -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
*
Expand Down
56 changes: 51 additions & 5 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,23 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
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];
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 0b2d8a7

Please sign in to comment.