diff options
author | Patrick McHardy <kaber@trash.net> | 2015-04-11 05:46:38 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-04-13 14:12:31 -0400 |
commit | 0b2d8a7b638b5034d2d68f6add8af94daaa1d4cd (patch) | |
tree | 0e10c271d522dd144f22e474af5f73a7c4214091 /net | |
parent | 24477e57412a7a7dea62637ac990bc5c1cff0665 (diff) |
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: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_tables_api.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index ed0e70ea2bc5..e97bee59fe08 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -1545,6 +1545,23 @@ nla_put_failure: | |||
1545 | return -1; | 1545 | return -1; |
1546 | }; | 1546 | }; |
1547 | 1547 | ||
1548 | int nft_expr_dump(struct sk_buff *skb, unsigned int attr, | ||
1549 | const struct nft_expr *expr) | ||
1550 | { | ||
1551 | struct nlattr *nest; | ||
1552 | |||
1553 | nest = nla_nest_start(skb, attr); | ||
1554 | if (!nest) | ||
1555 | goto nla_put_failure; | ||
1556 | if (nf_tables_fill_expr_info(skb, expr) < 0) | ||
1557 | goto nla_put_failure; | ||
1558 | nla_nest_end(skb, nest); | ||
1559 | return 0; | ||
1560 | |||
1561 | nla_put_failure: | ||
1562 | return -1; | ||
1563 | } | ||
1564 | |||
1548 | struct nft_expr_info { | 1565 | struct nft_expr_info { |
1549 | const struct nft_expr_ops *ops; | 1566 | const struct nft_expr_ops *ops; |
1550 | struct nlattr *tb[NFT_EXPR_MAXATTR + 1]; | 1567 | struct nlattr *tb[NFT_EXPR_MAXATTR + 1]; |
@@ -1622,6 +1639,39 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx, | |||
1622 | module_put(expr->ops->type->owner); | 1639 | module_put(expr->ops->type->owner); |
1623 | } | 1640 | } |
1624 | 1641 | ||
1642 | struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, | ||
1643 | const struct nlattr *nla) | ||
1644 | { | ||
1645 | struct nft_expr_info info; | ||
1646 | struct nft_expr *expr; | ||
1647 | int err; | ||
1648 | |||
1649 | err = nf_tables_expr_parse(ctx, nla, &info); | ||
1650 | if (err < 0) | ||
1651 | goto err1; | ||
1652 | |||
1653 | err = -ENOMEM; | ||
1654 | expr = kzalloc(info.ops->size, GFP_KERNEL); | ||
1655 | if (expr == NULL) | ||
1656 | goto err2; | ||
1657 | |||
1658 | err = nf_tables_newexpr(ctx, &info, expr); | ||
1659 | if (err < 0) | ||
1660 | goto err2; | ||
1661 | |||
1662 | return expr; | ||
1663 | err2: | ||
1664 | module_put(info.ops->type->owner); | ||
1665 | err1: | ||
1666 | return ERR_PTR(err); | ||
1667 | } | ||
1668 | |||
1669 | void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr) | ||
1670 | { | ||
1671 | nf_tables_expr_destroy(ctx, expr); | ||
1672 | kfree(expr); | ||
1673 | } | ||
1674 | |||
1625 | /* | 1675 | /* |
1626 | * Rules | 1676 | * Rules |
1627 | */ | 1677 | */ |
@@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, | |||
1703 | if (list == NULL) | 1753 | if (list == NULL) |
1704 | goto nla_put_failure; | 1754 | goto nla_put_failure; |
1705 | nft_rule_for_each_expr(expr, next, rule) { | 1755 | nft_rule_for_each_expr(expr, next, rule) { |
1706 | struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM); | 1756 | if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0) |
1707 | if (elem == NULL) | ||
1708 | goto nla_put_failure; | ||
1709 | if (nf_tables_fill_expr_info(skb, expr) < 0) | ||
1710 | goto nla_put_failure; | 1757 | goto nla_put_failure; |
1711 | nla_nest_end(skb, elem); | ||
1712 | } | 1758 | } |
1713 | nla_nest_end(skb, list); | 1759 | nla_nest_end(skb, list); |
1714 | 1760 | ||