aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-11-24 14:39:10 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2013-12-07 16:55:48 -0500
commitcf9dc09d0949f0b5953fb08caa10bba0dc7ee71f (patch)
tree87287d9503fcd06250657358b9036fbafa7a1b81
parentb4ef4ce09308955d1aa54a289c0162607b3aa16c (diff)
netfilter: nf_tables: fix missing rules flushing per table
This patch allows you to atomically remove all rules stored in a table via the NFT_MSG_DELRULE command. You only need to indicate the specific table and no chain to flush all rules stored in that table. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nf_tables_api.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index dcddc49c0e08..f93b7d06f4be 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1717,6 +1717,19 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
1717 return -ENOENT; 1717 return -ENOENT;
1718} 1718}
1719 1719
1720static int nf_table_delrule_by_chain(struct nft_ctx *ctx)
1721{
1722 struct nft_rule *rule;
1723 int err;
1724
1725 list_for_each_entry(rule, &ctx->chain->rules, list) {
1726 err = nf_tables_delrule_one(ctx, rule);
1727 if (err < 0)
1728 return err;
1729 }
1730 return 0;
1731}
1732
1720static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, 1733static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
1721 const struct nlmsghdr *nlh, 1734 const struct nlmsghdr *nlh,
1722 const struct nlattr * const nla[]) 1735 const struct nlattr * const nla[])
@@ -1725,8 +1738,8 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
1725 const struct nft_af_info *afi; 1738 const struct nft_af_info *afi;
1726 struct net *net = sock_net(skb->sk); 1739 struct net *net = sock_net(skb->sk);
1727 const struct nft_table *table; 1740 const struct nft_table *table;
1728 struct nft_chain *chain; 1741 struct nft_chain *chain = NULL;
1729 struct nft_rule *rule, *tmp; 1742 struct nft_rule *rule;
1730 int family = nfmsg->nfgen_family, err = 0; 1743 int family = nfmsg->nfgen_family, err = 0;
1731 struct nft_ctx ctx; 1744 struct nft_ctx ctx;
1732 1745
@@ -1738,22 +1751,29 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
1738 if (IS_ERR(table)) 1751 if (IS_ERR(table))
1739 return PTR_ERR(table); 1752 return PTR_ERR(table);
1740 1753
1741 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); 1754 if (nla[NFTA_RULE_CHAIN]) {
1742 if (IS_ERR(chain)) 1755 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1743 return PTR_ERR(chain); 1756 if (IS_ERR(chain))
1757 return PTR_ERR(chain);
1758 }
1744 1759
1745 nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); 1760 nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
1746 1761
1747 if (nla[NFTA_RULE_HANDLE]) { 1762 if (chain) {
1748 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]); 1763 if (nla[NFTA_RULE_HANDLE]) {
1749 if (IS_ERR(rule)) 1764 rule = nf_tables_rule_lookup(chain,
1750 return PTR_ERR(rule); 1765 nla[NFTA_RULE_HANDLE]);
1766 if (IS_ERR(rule))
1767 return PTR_ERR(rule);
1751 1768
1752 err = nf_tables_delrule_one(&ctx, rule);
1753 } else {
1754 /* Remove all rules in this chain */
1755 list_for_each_entry_safe(rule, tmp, &chain->rules, list) {
1756 err = nf_tables_delrule_one(&ctx, rule); 1769 err = nf_tables_delrule_one(&ctx, rule);
1770 } else {
1771 err = nf_table_delrule_by_chain(&ctx);
1772 }
1773 } else {
1774 list_for_each_entry(chain, &table->chains, list) {
1775 ctx.chain = chain;
1776 err = nf_table_delrule_by_chain(&ctx);
1757 if (err < 0) 1777 if (err < 0)
1758 break; 1778 break;
1759 } 1779 }