aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/nf_tables.h13
-rw-r--r--net/netfilter/nf_tables_api.c56
2 files changed, 64 insertions, 5 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index cb42da1011ef..e21623cb7b20 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1,6 +1,7 @@
1#ifndef _NET_NF_TABLES_H 1#ifndef _NET_NF_TABLES_H
2#define _NET_NF_TABLES_H 2#define _NET_NF_TABLES_H
3 3
4#include <linux/module.h>
4#include <linux/list.h> 5#include <linux/list.h>
5#include <linux/netfilter.h> 6#include <linux/netfilter.h>
6#include <linux/netfilter/nfnetlink.h> 7#include <linux/netfilter/nfnetlink.h>
@@ -641,6 +642,18 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
641 return (void *)expr->data; 642 return (void *)expr->data;
642} 643}
643 644
645struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
646 const struct nlattr *nla);
647void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
648int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
649 const struct nft_expr *expr);
650
651static inline void nft_expr_clone(struct nft_expr *dst, struct nft_expr *src)
652{
653 __module_get(src->ops->type->owner);
654 memcpy(dst, src, src->ops->size);
655}
656
644/** 657/**
645 * struct nft_rule - nf_tables rule 658 * struct nft_rule - nf_tables rule
646 * 659 *
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
1548int 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
1561nla_put_failure:
1562 return -1;
1563}
1564
1548struct nft_expr_info { 1565struct 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
1642struct 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;
1663err2:
1664 module_put(info.ops->type->owner);
1665err1:
1666 return ERR_PTR(err);
1667}
1668
1669void 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