diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-11-24 14:39:10 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-12-07 16:55:48 -0500 |
commit | cf9dc09d0949f0b5953fb08caa10bba0dc7ee71f (patch) | |
tree | 87287d9503fcd06250657358b9036fbafa7a1b81 | |
parent | b4ef4ce09308955d1aa54a289c0162607b3aa16c (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.c | 46 |
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 | ||
1720 | static 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 | |||
1720 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | 1733 | static 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 | } |