aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-06-14 11:29:18 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2016-06-24 05:03:24 -0400
commitf2a6d766765d2794e26e25655d4ffcfe29c3ec2f (patch)
treeec11de276afb1b026de1380a77d75a67b7772fe6
parent889f7ee7c6e84251215d43cbc856ea116c72d3f2 (diff)
netfilter: nf_tables: add generation mask to tables
This patch addresses two problems: 1) The netlink dump is inconsistent when interfering with an ongoing transaction update for several reasons: 1.a) We don't honor the internal NFT_TABLE_INACTIVE flag, and we should be skipping these inactive objects in the dump. 1.b) We perform speculative deletion during the preparation phase, that may result in skipping active objects. 1.c) The listing order changes, which generates noise when tracking incremental ruleset update via tools like git or our own testsuite. 2) We don't allow to add and to update the object in the same batch, eg. add table x; add table x { flags dormant\; }. In order to resolve these problems: 1) If the user requests a deletion, the object becomes inactive in the next generation. Then, ignore objects that scheduled to be deleted from the lookup path, as they will be effectively removed in the next generation. 2) From the get/dump path, if the object is not currently active, we skip it. 3) Support 'add X -> update X' sequence from a transaction. After this update, we obtain a consistent list as long as we stay in the same generation. The userspace side can detect interferences through the generation counter so it can restart the dumping. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/net/netfilter/nf_tables.h6
-rw-r--r--net/netfilter/nf_tables_api.c101
2 files changed, 62 insertions, 45 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index d0778cbaf7f1..05c9a64b39aa 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -838,6 +838,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
838 * @hgenerator: handle generator state 838 * @hgenerator: handle generator state
839 * @use: number of chain references to this table 839 * @use: number of chain references to this table
840 * @flags: table flag (see enum nft_table_flags) 840 * @flags: table flag (see enum nft_table_flags)
841 * @genmask: generation mask
841 * @name: name of the table 842 * @name: name of the table
842 */ 843 */
843struct nft_table { 844struct nft_table {
@@ -846,7 +847,8 @@ struct nft_table {
846 struct list_head sets; 847 struct list_head sets;
847 u64 hgenerator; 848 u64 hgenerator;
848 u32 use; 849 u32 use;
849 u16 flags; 850 u16 flags:14,
851 genmask:2;
850 char name[NFT_TABLE_MAXNAMELEN]; 852 char name[NFT_TABLE_MAXNAMELEN];
851}; 853};
852 854
@@ -992,6 +994,8 @@ static inline u8 nft_genmask_cur(const struct net *net)
992/* After committing the ruleset, clear the stale generation bit. */ 994/* After committing the ruleset, clear the stale generation bit. */
993#define nft_clear(__net, __obj) \ 995#define nft_clear(__net, __obj) \
994 (__obj)->genmask &= ~nft_genmask_next(__net) 996 (__obj)->genmask &= ~nft_genmask_next(__net)
997#define nft_active_genmask(__obj, __genmask) \
998 !((__obj)->genmask & __genmask)
995 999
996/* 1000/*
997 * Set element transaction helpers 1001 * Set element transaction helpers
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d9f0f0797dec..a4a77d60e631 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -175,9 +175,6 @@ static void nf_tables_unregister_hooks(const struct nft_table *table,
175 nft_unregister_basechain(nft_base_chain(chain), hook_nops); 175 nft_unregister_basechain(nft_base_chain(chain), hook_nops);
176} 176}
177 177
178/* Internal table flags */
179#define NFT_TABLE_INACTIVE (1 << 15)
180
181static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) 178static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
182{ 179{
183 struct nft_trans *trans; 180 struct nft_trans *trans;
@@ -187,7 +184,7 @@ static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
187 return -ENOMEM; 184 return -ENOMEM;
188 185
189 if (msg_type == NFT_MSG_NEWTABLE) 186 if (msg_type == NFT_MSG_NEWTABLE)
190 ctx->table->flags |= NFT_TABLE_INACTIVE; 187 nft_activate_next(ctx->net, ctx->table);
191 188
192 list_add_tail(&trans->list, &ctx->net->nft.commit_list); 189 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
193 return 0; 190 return 0;
@@ -201,7 +198,7 @@ static int nft_deltable(struct nft_ctx *ctx)
201 if (err < 0) 198 if (err < 0)
202 return err; 199 return err;
203 200
204 list_del_rcu(&ctx->table->list); 201 nft_deactivate_next(ctx->net, ctx->table);
205 return err; 202 return err;
206} 203}
207 204
@@ -334,26 +331,29 @@ static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
334 */ 331 */
335 332
336static struct nft_table *nft_table_lookup(const struct nft_af_info *afi, 333static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
337 const struct nlattr *nla) 334 const struct nlattr *nla,
335 u8 genmask)
338{ 336{
339 struct nft_table *table; 337 struct nft_table *table;
340 338
341 list_for_each_entry(table, &afi->tables, list) { 339 list_for_each_entry(table, &afi->tables, list) {
342 if (!nla_strcmp(nla, table->name)) 340 if (!nla_strcmp(nla, table->name) &&
341 nft_active_genmask(table, genmask))
343 return table; 342 return table;
344 } 343 }
345 return NULL; 344 return NULL;
346} 345}
347 346
348static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi, 347static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
349 const struct nlattr *nla) 348 const struct nlattr *nla,
349 u8 genmask)
350{ 350{
351 struct nft_table *table; 351 struct nft_table *table;
352 352
353 if (nla == NULL) 353 if (nla == NULL)
354 return ERR_PTR(-EINVAL); 354 return ERR_PTR(-EINVAL);
355 355
356 table = nft_table_lookup(afi, nla); 356 table = nft_table_lookup(afi, nla, genmask);
357 if (table != NULL) 357 if (table != NULL)
358 return table; 358 return table;
359 359
@@ -494,6 +494,8 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
494 if (idx > s_idx) 494 if (idx > s_idx)
495 memset(&cb->args[1], 0, 495 memset(&cb->args[1], 0,
496 sizeof(cb->args) - sizeof(cb->args[0])); 496 sizeof(cb->args) - sizeof(cb->args[0]));
497 if (!nft_is_active(net, table))
498 continue;
497 if (nf_tables_fill_table_info(skb, net, 499 if (nf_tables_fill_table_info(skb, net,
498 NETLINK_CB(cb->skb).portid, 500 NETLINK_CB(cb->skb).portid,
499 cb->nlh->nlmsg_seq, 501 cb->nlh->nlmsg_seq,
@@ -518,6 +520,7 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk,
518 const struct nlattr * const nla[]) 520 const struct nlattr * const nla[])
519{ 521{
520 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 522 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
523 u8 genmask = nft_genmask_cur(net);
521 const struct nft_af_info *afi; 524 const struct nft_af_info *afi;
522 const struct nft_table *table; 525 const struct nft_table *table;
523 struct sk_buff *skb2; 526 struct sk_buff *skb2;
@@ -535,11 +538,9 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk,
535 if (IS_ERR(afi)) 538 if (IS_ERR(afi))
536 return PTR_ERR(afi); 539 return PTR_ERR(afi);
537 540
538 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]); 541 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
539 if (IS_ERR(table)) 542 if (IS_ERR(table))
540 return PTR_ERR(table); 543 return PTR_ERR(table);
541 if (table->flags & NFT_TABLE_INACTIVE)
542 return -ENOENT;
543 544
544 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 545 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
545 if (!skb2) 546 if (!skb2)
@@ -648,6 +649,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
648 const struct nlattr * const nla[]) 649 const struct nlattr * const nla[])
649{ 650{
650 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 651 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
652 u8 genmask = nft_genmask_next(net);
651 const struct nlattr *name; 653 const struct nlattr *name;
652 struct nft_af_info *afi; 654 struct nft_af_info *afi;
653 struct nft_table *table; 655 struct nft_table *table;
@@ -661,7 +663,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
661 return PTR_ERR(afi); 663 return PTR_ERR(afi);
662 664
663 name = nla[NFTA_TABLE_NAME]; 665 name = nla[NFTA_TABLE_NAME];
664 table = nf_tables_table_lookup(afi, name); 666 table = nf_tables_table_lookup(afi, name, genmask);
665 if (IS_ERR(table)) { 667 if (IS_ERR(table)) {
666 if (PTR_ERR(table) != -ENOENT) 668 if (PTR_ERR(table) != -ENOENT)
667 return PTR_ERR(table); 669 return PTR_ERR(table);
@@ -669,8 +671,6 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
669 } 671 }
670 672
671 if (table != NULL) { 673 if (table != NULL) {
672 if (table->flags & NFT_TABLE_INACTIVE)
673 return -ENOENT;
674 if (nlh->nlmsg_flags & NLM_F_EXCL) 674 if (nlh->nlmsg_flags & NLM_F_EXCL)
675 return -EEXIST; 675 return -EEXIST;
676 if (nlh->nlmsg_flags & NLM_F_REPLACE) 676 if (nlh->nlmsg_flags & NLM_F_REPLACE)
@@ -765,6 +765,9 @@ static int nft_flush(struct nft_ctx *ctx, int family)
765 765
766 ctx->afi = afi; 766 ctx->afi = afi;
767 list_for_each_entry_safe(table, nt, &afi->tables, list) { 767 list_for_each_entry_safe(table, nt, &afi->tables, list) {
768 if (!nft_is_active_next(ctx->net, table))
769 continue;
770
768 if (nla[NFTA_TABLE_NAME] && 771 if (nla[NFTA_TABLE_NAME] &&
769 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0) 772 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
770 continue; 773 continue;
@@ -785,6 +788,7 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,
785 const struct nlattr * const nla[]) 788 const struct nlattr * const nla[])
786{ 789{
787 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 790 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
791 u8 genmask = nft_genmask_next(net);
788 struct nft_af_info *afi; 792 struct nft_af_info *afi;
789 struct nft_table *table; 793 struct nft_table *table;
790 int family = nfmsg->nfgen_family; 794 int family = nfmsg->nfgen_family;
@@ -798,7 +802,7 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,
798 if (IS_ERR(afi)) 802 if (IS_ERR(afi))
799 return PTR_ERR(afi); 803 return PTR_ERR(afi);
800 804
801 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]); 805 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
802 if (IS_ERR(table)) 806 if (IS_ERR(table))
803 return PTR_ERR(table); 807 return PTR_ERR(table);
804 808
@@ -1074,6 +1078,7 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1074 const struct nlattr * const nla[]) 1078 const struct nlattr * const nla[])
1075{ 1079{
1076 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1080 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1081 u8 genmask = nft_genmask_cur(net);
1077 const struct nft_af_info *afi; 1082 const struct nft_af_info *afi;
1078 const struct nft_table *table; 1083 const struct nft_table *table;
1079 const struct nft_chain *chain; 1084 const struct nft_chain *chain;
@@ -1092,11 +1097,9 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1092 if (IS_ERR(afi)) 1097 if (IS_ERR(afi))
1093 return PTR_ERR(afi); 1098 return PTR_ERR(afi);
1094 1099
1095 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1100 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1096 if (IS_ERR(table)) 1101 if (IS_ERR(table))
1097 return PTR_ERR(table); 1102 return PTR_ERR(table);
1098 if (table->flags & NFT_TABLE_INACTIVE)
1099 return -ENOENT;
1100 1103
1101 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]); 1104 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
1102 if (IS_ERR(chain)) 1105 if (IS_ERR(chain))
@@ -1201,6 +1204,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1201 struct nft_chain *chain; 1204 struct nft_chain *chain;
1202 struct nft_base_chain *basechain = NULL; 1205 struct nft_base_chain *basechain = NULL;
1203 struct nlattr *ha[NFTA_HOOK_MAX + 1]; 1206 struct nlattr *ha[NFTA_HOOK_MAX + 1];
1207 u8 genmask = nft_genmask_next(net);
1204 int family = nfmsg->nfgen_family; 1208 int family = nfmsg->nfgen_family;
1205 struct net_device *dev = NULL; 1209 struct net_device *dev = NULL;
1206 u8 policy = NF_ACCEPT; 1210 u8 policy = NF_ACCEPT;
@@ -1217,7 +1221,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1217 if (IS_ERR(afi)) 1221 if (IS_ERR(afi))
1218 return PTR_ERR(afi); 1222 return PTR_ERR(afi);
1219 1223
1220 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1224 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1221 if (IS_ERR(table)) 1225 if (IS_ERR(table))
1222 return PTR_ERR(table); 1226 return PTR_ERR(table);
1223 1227
@@ -1449,6 +1453,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1449 const struct nlattr * const nla[]) 1453 const struct nlattr * const nla[])
1450{ 1454{
1451 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1455 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1456 u8 genmask = nft_genmask_next(net);
1452 struct nft_af_info *afi; 1457 struct nft_af_info *afi;
1453 struct nft_table *table; 1458 struct nft_table *table;
1454 struct nft_chain *chain; 1459 struct nft_chain *chain;
@@ -1459,7 +1464,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1459 if (IS_ERR(afi)) 1464 if (IS_ERR(afi))
1460 return PTR_ERR(afi); 1465 return PTR_ERR(afi);
1461 1466
1462 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1467 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1463 if (IS_ERR(table)) 1468 if (IS_ERR(table))
1464 return PTR_ERR(table); 1469 return PTR_ERR(table);
1465 1470
@@ -1901,6 +1906,7 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk,
1901 const struct nlattr * const nla[]) 1906 const struct nlattr * const nla[])
1902{ 1907{
1903 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1908 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1909 u8 genmask = nft_genmask_cur(net);
1904 const struct nft_af_info *afi; 1910 const struct nft_af_info *afi;
1905 const struct nft_table *table; 1911 const struct nft_table *table;
1906 const struct nft_chain *chain; 1912 const struct nft_chain *chain;
@@ -1920,11 +1926,9 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk,
1920 if (IS_ERR(afi)) 1926 if (IS_ERR(afi))
1921 return PTR_ERR(afi); 1927 return PTR_ERR(afi);
1922 1928
1923 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 1929 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
1924 if (IS_ERR(table)) 1930 if (IS_ERR(table))
1925 return PTR_ERR(table); 1931 return PTR_ERR(table);
1926 if (table->flags & NFT_TABLE_INACTIVE)
1927 return -ENOENT;
1928 1932
1929 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); 1933 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1930 if (IS_ERR(chain)) 1934 if (IS_ERR(chain))
@@ -1979,6 +1983,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
1979 const struct nlattr * const nla[]) 1983 const struct nlattr * const nla[])
1980{ 1984{
1981 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1985 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1986 u8 genmask = nft_genmask_next(net);
1982 struct nft_af_info *afi; 1987 struct nft_af_info *afi;
1983 struct nft_table *table; 1988 struct nft_table *table;
1984 struct nft_chain *chain; 1989 struct nft_chain *chain;
@@ -1999,7 +2004,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
1999 if (IS_ERR(afi)) 2004 if (IS_ERR(afi))
2000 return PTR_ERR(afi); 2005 return PTR_ERR(afi);
2001 2006
2002 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 2007 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2003 if (IS_ERR(table)) 2008 if (IS_ERR(table))
2004 return PTR_ERR(table); 2009 return PTR_ERR(table);
2005 2010
@@ -2144,6 +2149,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2144 const struct nlattr * const nla[]) 2149 const struct nlattr * const nla[])
2145{ 2150{
2146 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2151 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2152 u8 genmask = nft_genmask_next(net);
2147 struct nft_af_info *afi; 2153 struct nft_af_info *afi;
2148 struct nft_table *table; 2154 struct nft_table *table;
2149 struct nft_chain *chain = NULL; 2155 struct nft_chain *chain = NULL;
@@ -2155,7 +2161,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2155 if (IS_ERR(afi)) 2161 if (IS_ERR(afi))
2156 return PTR_ERR(afi); 2162 return PTR_ERR(afi);
2157 2163
2158 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 2164 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2159 if (IS_ERR(table)) 2165 if (IS_ERR(table))
2160 return PTR_ERR(table); 2166 return PTR_ERR(table);
2161 2167
@@ -2309,7 +2315,8 @@ static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
2309static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net, 2315static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2310 const struct sk_buff *skb, 2316 const struct sk_buff *skb,
2311 const struct nlmsghdr *nlh, 2317 const struct nlmsghdr *nlh,
2312 const struct nlattr * const nla[]) 2318 const struct nlattr * const nla[],
2319 u8 genmask)
2313{ 2320{
2314 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2321 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2315 struct nft_af_info *afi = NULL; 2322 struct nft_af_info *afi = NULL;
@@ -2325,7 +2332,8 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2325 if (afi == NULL) 2332 if (afi == NULL)
2326 return -EAFNOSUPPORT; 2333 return -EAFNOSUPPORT;
2327 2334
2328 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); 2335 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE],
2336 genmask);
2329 if (IS_ERR(table)) 2337 if (IS_ERR(table))
2330 return PTR_ERR(table); 2338 return PTR_ERR(table);
2331 } 2339 }
@@ -2586,6 +2594,7 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk,
2586 struct sk_buff *skb, const struct nlmsghdr *nlh, 2594 struct sk_buff *skb, const struct nlmsghdr *nlh,
2587 const struct nlattr * const nla[]) 2595 const struct nlattr * const nla[])
2588{ 2596{
2597 u8 genmask = nft_genmask_cur(net);
2589 const struct nft_set *set; 2598 const struct nft_set *set;
2590 struct nft_ctx ctx; 2599 struct nft_ctx ctx;
2591 struct sk_buff *skb2; 2600 struct sk_buff *skb2;
@@ -2593,7 +2602,7 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk,
2593 int err; 2602 int err;
2594 2603
2595 /* Verify existence before starting dump */ 2604 /* Verify existence before starting dump */
2596 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla); 2605 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
2597 if (err < 0) 2606 if (err < 0)
2598 return err; 2607 return err;
2599 2608
@@ -2661,6 +2670,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2661 const struct nlattr * const nla[]) 2670 const struct nlattr * const nla[])
2662{ 2671{
2663 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2672 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2673 u8 genmask = nft_genmask_next(net);
2664 const struct nft_set_ops *ops; 2674 const struct nft_set_ops *ops;
2665 struct nft_af_info *afi; 2675 struct nft_af_info *afi;
2666 struct nft_table *table; 2676 struct nft_table *table;
@@ -2758,7 +2768,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2758 if (IS_ERR(afi)) 2768 if (IS_ERR(afi))
2759 return PTR_ERR(afi); 2769 return PTR_ERR(afi);
2760 2770
2761 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); 2771 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask);
2762 if (IS_ERR(table)) 2772 if (IS_ERR(table))
2763 return PTR_ERR(table); 2773 return PTR_ERR(table);
2764 2774
@@ -2863,6 +2873,7 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
2863 const struct nlattr * const nla[]) 2873 const struct nlattr * const nla[])
2864{ 2874{
2865 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2875 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2876 u8 genmask = nft_genmask_next(net);
2866 struct nft_set *set; 2877 struct nft_set *set;
2867 struct nft_ctx ctx; 2878 struct nft_ctx ctx;
2868 int err; 2879 int err;
@@ -2872,7 +2883,7 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
2872 if (nla[NFTA_SET_TABLE] == NULL) 2883 if (nla[NFTA_SET_TABLE] == NULL)
2873 return -EINVAL; 2884 return -EINVAL;
2874 2885
2875 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla); 2886 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
2876 if (err < 0) 2887 if (err < 0)
2877 return err; 2888 return err;
2878 2889
@@ -3001,7 +3012,8 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
3001static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net, 3012static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3002 const struct sk_buff *skb, 3013 const struct sk_buff *skb,
3003 const struct nlmsghdr *nlh, 3014 const struct nlmsghdr *nlh,
3004 const struct nlattr * const nla[]) 3015 const struct nlattr * const nla[],
3016 u8 genmask)
3005{ 3017{
3006 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 3018 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3007 struct nft_af_info *afi; 3019 struct nft_af_info *afi;
@@ -3011,7 +3023,8 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3011 if (IS_ERR(afi)) 3023 if (IS_ERR(afi))
3012 return PTR_ERR(afi); 3024 return PTR_ERR(afi);
3013 3025
3014 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]); 3026 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE],
3027 genmask);
3015 if (IS_ERR(table)) 3028 if (IS_ERR(table))
3016 return PTR_ERR(table); 3029 return PTR_ERR(table);
3017 3030
@@ -3108,6 +3121,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
3108static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) 3121static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3109{ 3122{
3110 struct net *net = sock_net(skb->sk); 3123 struct net *net = sock_net(skb->sk);
3124 u8 genmask = nft_genmask_cur(net);
3111 const struct nft_set *set; 3125 const struct nft_set *set;
3112 struct nft_set_dump_args args; 3126 struct nft_set_dump_args args;
3113 struct nft_ctx ctx; 3127 struct nft_ctx ctx;
@@ -3124,11 +3138,9 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3124 return err; 3138 return err;
3125 3139
3126 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh, 3140 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
3127 (void *)nla); 3141 (void *)nla, genmask);
3128 if (err < 0) 3142 if (err < 0)
3129 return err; 3143 return err;
3130 if (ctx.table->flags & NFT_TABLE_INACTIVE)
3131 return -ENOENT;
3132 3144
3133 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3145 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3134 if (IS_ERR(set)) 3146 if (IS_ERR(set))
@@ -3187,15 +3199,14 @@ static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3187 struct sk_buff *skb, const struct nlmsghdr *nlh, 3199 struct sk_buff *skb, const struct nlmsghdr *nlh,
3188 const struct nlattr * const nla[]) 3200 const struct nlattr * const nla[])
3189{ 3201{
3202 u8 genmask = nft_genmask_cur(net);
3190 const struct nft_set *set; 3203 const struct nft_set *set;
3191 struct nft_ctx ctx; 3204 struct nft_ctx ctx;
3192 int err; 3205 int err;
3193 3206
3194 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla); 3207 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3195 if (err < 0) 3208 if (err < 0)
3196 return err; 3209 return err;
3197 if (ctx.table->flags & NFT_TABLE_INACTIVE)
3198 return -ENOENT;
3199 3210
3200 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3211 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3201 if (IS_ERR(set)) 3212 if (IS_ERR(set))
@@ -3519,6 +3530,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
3519 struct sk_buff *skb, const struct nlmsghdr *nlh, 3530 struct sk_buff *skb, const struct nlmsghdr *nlh,
3520 const struct nlattr * const nla[]) 3531 const struct nlattr * const nla[])
3521{ 3532{
3533 u8 genmask = nft_genmask_next(net);
3522 const struct nlattr *attr; 3534 const struct nlattr *attr;
3523 struct nft_set *set; 3535 struct nft_set *set;
3524 struct nft_ctx ctx; 3536 struct nft_ctx ctx;
@@ -3527,7 +3539,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
3527 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 3539 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3528 return -EINVAL; 3540 return -EINVAL;
3529 3541
3530 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla); 3542 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3531 if (err < 0) 3543 if (err < 0)
3532 return err; 3544 return err;
3533 3545
@@ -3641,6 +3653,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
3641 struct sk_buff *skb, const struct nlmsghdr *nlh, 3653 struct sk_buff *skb, const struct nlmsghdr *nlh,
3642 const struct nlattr * const nla[]) 3654 const struct nlattr * const nla[])
3643{ 3655{
3656 u8 genmask = nft_genmask_next(net);
3644 const struct nlattr *attr; 3657 const struct nlattr *attr;
3645 struct nft_set *set; 3658 struct nft_set *set;
3646 struct nft_ctx ctx; 3659 struct nft_ctx ctx;
@@ -3649,7 +3662,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
3649 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 3662 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3650 return -EINVAL; 3663 return -EINVAL;
3651 3664
3652 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla); 3665 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3653 if (err < 0) 3666 if (err < 0)
3654 return err; 3667 return err;
3655 3668
@@ -3926,12 +3939,13 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
3926 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT; 3939 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
3927 } 3940 }
3928 } else { 3941 } else {
3929 trans->ctx.table->flags &= ~NFT_TABLE_INACTIVE; 3942 nft_clear(net, trans->ctx.table);
3930 } 3943 }
3931 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE); 3944 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
3932 nft_trans_destroy(trans); 3945 nft_trans_destroy(trans);
3933 break; 3946 break;
3934 case NFT_MSG_DELTABLE: 3947 case NFT_MSG_DELTABLE:
3948 list_del_rcu(&trans->ctx.table->list);
3935 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE); 3949 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
3936 break; 3950 break;
3937 case NFT_MSG_NEWCHAIN: 3951 case NFT_MSG_NEWCHAIN:
@@ -4057,8 +4071,7 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4057 } 4071 }
4058 break; 4072 break;
4059 case NFT_MSG_DELTABLE: 4073 case NFT_MSG_DELTABLE:
4060 list_add_tail_rcu(&trans->ctx.table->list, 4074 nft_clear(trans->ctx.net, trans->ctx.table);
4061 &trans->ctx.afi->tables);
4062 nft_trans_destroy(trans); 4075 nft_trans_destroy(trans);
4063 break; 4076 break;
4064 case NFT_MSG_NEWCHAIN: 4077 case NFT_MSG_NEWCHAIN: