e08b9b26d5b30214ab12c5dcabe1ebb072a1a47c
[oweals/openwrt.git] /
1 From: Pablo Neira Ayuso <pablo@netfilter.org>
2 Date: Tue, 9 Jan 2018 02:38:03 +0100
3 Subject: [PATCH] netfilter: nf_tables: add single table list for all families
4
5 Place all existing user defined tables in struct net *, instead of
6 having one list per family. This saves us from one level of indentation
7 in netlink dump functions.
8
9 Place pointer to struct nft_af_info in struct nft_table temporarily, as
10 we still need this to put back reference module reference counter on
11 table removal.
12
13 This patch comes in preparation for the removal of struct nft_af_info.
14
15 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
16 ---
17
18 --- a/include/net/netfilter/nf_tables.h
19 +++ b/include/net/netfilter/nf_tables.h
20 @@ -143,22 +143,22 @@ static inline void nft_data_debug(const
21   *     struct nft_ctx - nf_tables rule/set context
22   *
23   *     @net: net namespace
24 - *     @afi: address family info
25   *     @table: the table the chain is contained in
26   *     @chain: the chain the rule is contained in
27   *     @nla: netlink attributes
28   *     @portid: netlink portID of the original message
29   *     @seq: netlink sequence number
30 + *     @family: protocol family
31   *     @report: notify via unicast netlink message
32   */
33  struct nft_ctx {
34         struct net                      *net;
35 -       struct nft_af_info              *afi;
36         struct nft_table                *table;
37         struct nft_chain                *chain;
38         const struct nlattr * const     *nla;
39         u32                             portid;
40         u32                             seq;
41 +       u8                              family;
42         bool                            report;
43  };
44  
45 @@ -944,6 +944,7 @@ unsigned int nft_do_chain(struct nft_pkt
46   *     @use: number of chain references to this table
47   *     @flags: table flag (see enum nft_table_flags)
48   *     @genmask: generation mask
49 + *     @afinfo: address family info
50   *     @name: name of the table
51   */
52  struct nft_table {
53 @@ -956,6 +957,7 @@ struct nft_table {
54         u32                             use;
55         u16                             flags:14,
56                                         genmask:2;
57 +       struct nft_af_info              *afi;
58         char                            *name;
59  };
60  
61 @@ -965,13 +967,11 @@ struct nft_table {
62   *     @list: used internally
63   *     @family: address family
64   *     @owner: module owner
65 - *     @tables: used internally
66   */
67  struct nft_af_info {
68         struct list_head                list;
69         int                             family;
70         struct module                   *owner;
71 -       struct list_head                tables;
72  };
73  
74  int nft_register_afinfo(struct net *, struct nft_af_info *);
75 --- a/include/net/netns/nftables.h
76 +++ b/include/net/netns/nftables.h
77 @@ -8,6 +8,7 @@ struct nft_af_info;
78  
79  struct netns_nftables {
80         struct list_head        af_info;
81 +       struct list_head        tables;
82         struct list_head        commit_list;
83         struct nft_af_info      *ipv4;
84         struct nft_af_info      *ipv6;
85 --- a/net/netfilter/nf_tables_api.c
86 +++ b/net/netfilter/nf_tables_api.c
87 @@ -37,7 +37,6 @@ static LIST_HEAD(nf_tables_flowtables);
88   */
89  int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
90  {
91 -       INIT_LIST_HEAD(&afi->tables);
92         nfnl_lock(NFNL_SUBSYS_NFTABLES);
93         list_add_tail_rcu(&afi->list, &net->nft.af_info);
94         nfnl_unlock(NFNL_SUBSYS_NFTABLES);
95 @@ -99,13 +98,13 @@ static void nft_ctx_init(struct nft_ctx
96                          struct net *net,
97                          const struct sk_buff *skb,
98                          const struct nlmsghdr *nlh,
99 -                        struct nft_af_info *afi,
100 +                        u8 family,
101                          struct nft_table *table,
102                          struct nft_chain *chain,
103                          const struct nlattr * const *nla)
104  {
105         ctx->net        = net;
106 -       ctx->afi        = afi;
107 +       ctx->family     = family;
108         ctx->table      = table;
109         ctx->chain      = chain;
110         ctx->nla        = nla;
111 @@ -414,30 +413,31 @@ static int nft_delflowtable(struct nft_c
112   * Tables
113   */
114  
115 -static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
116 +static struct nft_table *nft_table_lookup(const struct net *net,
117                                           const struct nlattr *nla,
118 -                                         u8 genmask)
119 +                                         u8 family, u8 genmask)
120  {
121         struct nft_table *table;
122  
123 -       list_for_each_entry(table, &afi->tables, list) {
124 +       list_for_each_entry(table, &net->nft.tables, list) {
125                 if (!nla_strcmp(nla, table->name) &&
126 +                   table->afi->family == family &&
127                     nft_active_genmask(table, genmask))
128                         return table;
129         }
130         return NULL;
131  }
132  
133 -static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
134 +static struct nft_table *nf_tables_table_lookup(const struct net *net,
135                                                 const struct nlattr *nla,
136 -                                               u8 genmask)
137 +                                               u8 family, u8 genmask)
138  {
139         struct nft_table *table;
140  
141         if (nla == NULL)
142                 return ERR_PTR(-EINVAL);
143  
144 -       table = nft_table_lookup(afi, nla, genmask);
145 +       table = nft_table_lookup(net, nla, family, genmask);
146         if (table != NULL)
147                 return table;
148  
149 @@ -536,7 +536,7 @@ static void nf_tables_table_notify(const
150                 goto err;
151  
152         err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
153 -                                       event, 0, ctx->afi->family, ctx->table);
154 +                                       event, 0, ctx->family, ctx->table);
155         if (err < 0) {
156                 kfree_skb(skb);
157                 goto err;
158 @@ -553,7 +553,6 @@ static int nf_tables_dump_tables(struct
159                                  struct netlink_callback *cb)
160  {
161         const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
162 -       const struct nft_af_info *afi;
163         const struct nft_table *table;
164         unsigned int idx = 0, s_idx = cb->args[0];
165         struct net *net = sock_net(skb->sk);
166 @@ -562,30 +561,27 @@ static int nf_tables_dump_tables(struct
167         rcu_read_lock();
168         cb->seq = net->nft.base_seq;
169  
170 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
171 -               if (family != NFPROTO_UNSPEC && family != afi->family)
172 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
173 +               if (family != NFPROTO_UNSPEC && family != table->afi->family)
174                         continue;
175  
176 -               list_for_each_entry_rcu(table, &afi->tables, list) {
177 -                       if (idx < s_idx)
178 -                               goto cont;
179 -                       if (idx > s_idx)
180 -                               memset(&cb->args[1], 0,
181 -                                      sizeof(cb->args) - sizeof(cb->args[0]));
182 -                       if (!nft_is_active(net, table))
183 -                               continue;
184 -                       if (nf_tables_fill_table_info(skb, net,
185 -                                                     NETLINK_CB(cb->skb).portid,
186 -                                                     cb->nlh->nlmsg_seq,
187 -                                                     NFT_MSG_NEWTABLE,
188 -                                                     NLM_F_MULTI,
189 -                                                     afi->family, table) < 0)
190 -                               goto done;
191 +               if (idx < s_idx)
192 +                       goto cont;
193 +               if (idx > s_idx)
194 +                       memset(&cb->args[1], 0,
195 +                              sizeof(cb->args) - sizeof(cb->args[0]));
196 +               if (!nft_is_active(net, table))
197 +                       continue;
198 +               if (nf_tables_fill_table_info(skb, net,
199 +                                             NETLINK_CB(cb->skb).portid,
200 +                                             cb->nlh->nlmsg_seq,
201 +                                             NFT_MSG_NEWTABLE, NLM_F_MULTI,
202 +                                             table->afi->family, table) < 0)
203 +                       goto done;
204  
205 -                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
206 +               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
207  cont:
208 -                       idx++;
209 -               }
210 +               idx++;
211         }
212  done:
213         rcu_read_unlock();
214 @@ -617,7 +613,8 @@ static int nf_tables_gettable(struct net
215         if (IS_ERR(afi))
216                 return PTR_ERR(afi);
217  
218 -       table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
219 +       table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family,
220 +                                      genmask);
221         if (IS_ERR(table))
222                 return PTR_ERR(table);
223  
224 @@ -748,7 +745,7 @@ static int nf_tables_newtable(struct net
225                 return PTR_ERR(afi);
226  
227         name = nla[NFTA_TABLE_NAME];
228 -       table = nf_tables_table_lookup(afi, name, genmask);
229 +       table = nf_tables_table_lookup(net, name, afi->family, genmask);
230         if (IS_ERR(table)) {
231                 if (PTR_ERR(table) != -ENOENT)
232                         return PTR_ERR(table);
233 @@ -758,7 +755,7 @@ static int nf_tables_newtable(struct net
234                 if (nlh->nlmsg_flags & NLM_F_REPLACE)
235                         return -EOPNOTSUPP;
236  
237 -               nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
238 +               nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
239                 return nf_tables_updtable(&ctx);
240         }
241  
242 @@ -785,14 +782,15 @@ static int nf_tables_newtable(struct net
243         INIT_LIST_HEAD(&table->sets);
244         INIT_LIST_HEAD(&table->objects);
245         INIT_LIST_HEAD(&table->flowtables);
246 +       table->afi = afi;
247         table->flags = flags;
248  
249 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
250 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
251         err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
252         if (err < 0)
253                 goto err4;
254  
255 -       list_add_tail_rcu(&table->list, &afi->tables);
256 +       list_add_tail_rcu(&table->list, &net->nft.tables);
257         return 0;
258  err4:
259         kfree(table->name);
260 @@ -866,30 +864,28 @@ out:
261  
262  static int nft_flush(struct nft_ctx *ctx, int family)
263  {
264 -       struct nft_af_info *afi;
265         struct nft_table *table, *nt;
266         const struct nlattr * const *nla = ctx->nla;
267         int err = 0;
268  
269 -       list_for_each_entry(afi, &ctx->net->nft.af_info, list) {
270 -               if (family != AF_UNSPEC && afi->family != family)
271 +       list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) {
272 +               if (family != AF_UNSPEC && table->afi->family != family)
273                         continue;
274  
275 -               ctx->afi = afi;
276 -               list_for_each_entry_safe(table, nt, &afi->tables, list) {
277 -                       if (!nft_is_active_next(ctx->net, table))
278 -                               continue;
279 +               ctx->family = table->afi->family;
280  
281 -                       if (nla[NFTA_TABLE_NAME] &&
282 -                           nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
283 -                               continue;
284 +               if (!nft_is_active_next(ctx->net, table))
285 +                       continue;
286  
287 -                       ctx->table = table;
288 +               if (nla[NFTA_TABLE_NAME] &&
289 +                   nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
290 +                       continue;
291  
292 -                       err = nft_flush_table(ctx);
293 -                       if (err < 0)
294 -                               goto out;
295 -               }
296 +               ctx->table = table;
297 +
298 +               err = nft_flush_table(ctx);
299 +               if (err < 0)
300 +                       goto out;
301         }
302  out:
303         return err;
304 @@ -907,7 +903,7 @@ static int nf_tables_deltable(struct net
305         int family = nfmsg->nfgen_family;
306         struct nft_ctx ctx;
307  
308 -       nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla);
309 +       nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla);
310         if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
311                 return nft_flush(&ctx, family);
312  
313 @@ -915,7 +911,8 @@ static int nf_tables_deltable(struct net
314         if (IS_ERR(afi))
315                 return PTR_ERR(afi);
316  
317 -       table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
318 +       table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family,
319 +                                      genmask);
320         if (IS_ERR(table))
321                 return PTR_ERR(table);
322  
323 @@ -923,7 +920,7 @@ static int nf_tables_deltable(struct net
324             table->use > 0)
325                 return -EBUSY;
326  
327 -       ctx.afi = afi;
328 +       ctx.family = afi->family;
329         ctx.table = table;
330  
331         return nft_flush_table(&ctx);
332 @@ -935,7 +932,7 @@ static void nf_tables_table_destroy(stru
333  
334         kfree(ctx->table->name);
335         kfree(ctx->table);
336 -       module_put(ctx->afi->owner);
337 +       module_put(ctx->table->afi->owner);
338  }
339  
340  int nft_register_chain_type(const struct nf_chain_type *ctype)
341 @@ -1136,7 +1133,7 @@ static void nf_tables_chain_notify(const
342                 goto err;
343  
344         err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
345 -                                       event, 0, ctx->afi->family, ctx->table,
346 +                                       event, 0, ctx->family, ctx->table,
347                                         ctx->chain);
348         if (err < 0) {
349                 kfree_skb(skb);
350 @@ -1154,7 +1151,6 @@ static int nf_tables_dump_chains(struct
351                                  struct netlink_callback *cb)
352  {
353         const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
354 -       const struct nft_af_info *afi;
355         const struct nft_table *table;
356         const struct nft_chain *chain;
357         unsigned int idx = 0, s_idx = cb->args[0];
358 @@ -1164,31 +1160,30 @@ static int nf_tables_dump_chains(struct
359         rcu_read_lock();
360         cb->seq = net->nft.base_seq;
361  
362 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
363 -               if (family != NFPROTO_UNSPEC && family != afi->family)
364 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
365 +               if (family != NFPROTO_UNSPEC && family != table->afi->family)
366                         continue;
367  
368 -               list_for_each_entry_rcu(table, &afi->tables, list) {
369 -                       list_for_each_entry_rcu(chain, &table->chains, list) {
370 -                               if (idx < s_idx)
371 -                                       goto cont;
372 -                               if (idx > s_idx)
373 -                                       memset(&cb->args[1], 0,
374 -                                              sizeof(cb->args) - sizeof(cb->args[0]));
375 -                               if (!nft_is_active(net, chain))
376 -                                       continue;
377 -                               if (nf_tables_fill_chain_info(skb, net,
378 -                                                             NETLINK_CB(cb->skb).portid,
379 -                                                             cb->nlh->nlmsg_seq,
380 -                                                             NFT_MSG_NEWCHAIN,
381 -                                                             NLM_F_MULTI,
382 -                                                             afi->family, table, chain) < 0)
383 -                                       goto done;
384 +               list_for_each_entry_rcu(chain, &table->chains, list) {
385 +                       if (idx < s_idx)
386 +                               goto cont;
387 +                       if (idx > s_idx)
388 +                               memset(&cb->args[1], 0,
389 +                                      sizeof(cb->args) - sizeof(cb->args[0]));
390 +                       if (!nft_is_active(net, chain))
391 +                               continue;
392 +                       if (nf_tables_fill_chain_info(skb, net,
393 +                                                     NETLINK_CB(cb->skb).portid,
394 +                                                     cb->nlh->nlmsg_seq,
395 +                                                     NFT_MSG_NEWCHAIN,
396 +                                                     NLM_F_MULTI,
397 +                                                     table->afi->family, table,
398 +                                                     chain) < 0)
399 +                               goto done;
400  
401 -                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
402 +                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
403  cont:
404 -                               idx++;
405 -                       }
406 +                       idx++;
407                 }
408         }
409  done:
410 @@ -1222,7 +1217,8 @@ static int nf_tables_getchain(struct net
411         if (IS_ERR(afi))
412                 return PTR_ERR(afi);
413  
414 -       table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
415 +       table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family,
416 +                                      genmask);
417         if (IS_ERR(table))
418                 return PTR_ERR(table);
419  
420 @@ -1332,8 +1328,8 @@ struct nft_chain_hook {
421  
422  static int nft_chain_parse_hook(struct net *net,
423                                 const struct nlattr * const nla[],
424 -                               struct nft_af_info *afi,
425 -                               struct nft_chain_hook *hook, bool create)
426 +                               struct nft_chain_hook *hook, u8 family,
427 +                               bool create)
428  {
429         struct nlattr *ha[NFTA_HOOK_MAX + 1];
430         const struct nf_chain_type *type;
431 @@ -1352,10 +1348,10 @@ static int nft_chain_parse_hook(struct n
432         hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
433         hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
434  
435 -       type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT];
436 +       type = chain_type[family][NFT_CHAIN_T_DEFAULT];
437         if (nla[NFTA_CHAIN_TYPE]) {
438                 type = nf_tables_chain_type_lookup(nla[NFTA_CHAIN_TYPE],
439 -                                                  afi->family, create);
440 +                                                  family, create);
441                 if (IS_ERR(type))
442                         return PTR_ERR(type);
443         }
444 @@ -1367,7 +1363,7 @@ static int nft_chain_parse_hook(struct n
445         hook->type = type;
446  
447         hook->dev = NULL;
448 -       if (afi->family == NFPROTO_NETDEV) {
449 +       if (family == NFPROTO_NETDEV) {
450                 char ifname[IFNAMSIZ];
451  
452                 if (!ha[NFTA_HOOK_DEV]) {
453 @@ -1402,7 +1398,6 @@ static int nf_tables_addchain(struct nft
454  {
455         const struct nlattr * const *nla = ctx->nla;
456         struct nft_table *table = ctx->table;
457 -       struct nft_af_info *afi = ctx->afi;
458         struct nft_base_chain *basechain;
459         struct nft_stats __percpu *stats;
460         struct net *net = ctx->net;
461 @@ -1416,7 +1411,7 @@ static int nf_tables_addchain(struct nft
462                 struct nft_chain_hook hook;
463                 struct nf_hook_ops *ops;
464  
465 -               err = nft_chain_parse_hook(net, nla, afi, &hook, create);
466 +               err = nft_chain_parse_hook(net, nla, &hook, family, create);
467                 if (err < 0)
468                         return err;
469  
470 @@ -1508,7 +1503,7 @@ static int nf_tables_updchain(struct nft
471                 if (!nft_is_base_chain(chain))
472                         return -EBUSY;
473  
474 -               err = nft_chain_parse_hook(ctx->net, nla, ctx->afi, &hook,
475 +               err = nft_chain_parse_hook(ctx->net, nla, &hook, ctx->family,
476                                            create);
477                 if (err < 0)
478                         return err;
479 @@ -1618,7 +1613,8 @@ static int nf_tables_newchain(struct net
480         if (IS_ERR(afi))
481                 return PTR_ERR(afi);
482  
483 -       table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
484 +       table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family,
485 +                                      genmask);
486         if (IS_ERR(table))
487                 return PTR_ERR(table);
488  
489 @@ -1658,7 +1654,7 @@ static int nf_tables_newchain(struct net
490                 }
491         }
492  
493 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
494 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla);
495  
496         if (chain != NULL) {
497                 if (nlh->nlmsg_flags & NLM_F_EXCL)
498 @@ -1692,7 +1688,8 @@ static int nf_tables_delchain(struct net
499         if (IS_ERR(afi))
500                 return PTR_ERR(afi);
501  
502 -       table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
503 +       table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family,
504 +                                      genmask);
505         if (IS_ERR(table))
506                 return PTR_ERR(table);
507  
508 @@ -1704,7 +1701,7 @@ static int nf_tables_delchain(struct net
509             chain->use > 0)
510                 return -EBUSY;
511  
512 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
513 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla);
514  
515         use = chain->use;
516         list_for_each_entry(rule, &chain->rules, list) {
517 @@ -1869,7 +1866,7 @@ static int nf_tables_expr_parse(const st
518         if (err < 0)
519                 return err;
520  
521 -       type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]);
522 +       type = nft_expr_type_get(ctx->family, tb[NFTA_EXPR_NAME]);
523         if (IS_ERR(type))
524                 return PTR_ERR(type);
525  
526 @@ -2093,7 +2090,7 @@ static void nf_tables_rule_notify(const
527                 goto err;
528  
529         err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
530 -                                      event, 0, ctx->afi->family, ctx->table,
531 +                                      event, 0, ctx->family, ctx->table,
532                                        ctx->chain, rule);
533         if (err < 0) {
534                 kfree_skb(skb);
535 @@ -2117,7 +2114,6 @@ static int nf_tables_dump_rules(struct s
536  {
537         const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
538         const struct nft_rule_dump_ctx *ctx = cb->data;
539 -       const struct nft_af_info *afi;
540         const struct nft_table *table;
541         const struct nft_chain *chain;
542         const struct nft_rule *rule;
543 @@ -2128,39 +2124,37 @@ static int nf_tables_dump_rules(struct s
544         rcu_read_lock();
545         cb->seq = net->nft.base_seq;
546  
547 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
548 -               if (family != NFPROTO_UNSPEC && family != afi->family)
549 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
550 +               if (family != NFPROTO_UNSPEC && family != table->afi->family)
551 +                       continue;
552 +
553 +               if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0)
554                         continue;
555  
556 -               list_for_each_entry_rcu(table, &afi->tables, list) {
557 -                       if (ctx && ctx->table &&
558 -                           strcmp(ctx->table, table->name) != 0)
559 +               list_for_each_entry_rcu(chain, &table->chains, list) {
560 +                       if (ctx && ctx->chain &&
561 +                           strcmp(ctx->chain, chain->name) != 0)
562                                 continue;
563  
564 -                       list_for_each_entry_rcu(chain, &table->chains, list) {
565 -                               if (ctx && ctx->chain &&
566 -                                   strcmp(ctx->chain, chain->name) != 0)
567 -                                       continue;
568 -
569 -                               list_for_each_entry_rcu(rule, &chain->rules, list) {
570 -                                       if (!nft_is_active(net, rule))
571 -                                               goto cont;
572 -                                       if (idx < s_idx)
573 -                                               goto cont;
574 -                                       if (idx > s_idx)
575 -                                               memset(&cb->args[1], 0,
576 -                                                      sizeof(cb->args) - sizeof(cb->args[0]));
577 -                                       if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
578 -                                                                     cb->nlh->nlmsg_seq,
579 -                                                                     NFT_MSG_NEWRULE,
580 -                                                                     NLM_F_MULTI | NLM_F_APPEND,
581 -                                                                     afi->family, table, chain, rule) < 0)
582 -                                               goto done;
583 +                       list_for_each_entry_rcu(rule, &chain->rules, list) {
584 +                               if (!nft_is_active(net, rule))
585 +                                       goto cont;
586 +                               if (idx < s_idx)
587 +                                       goto cont;
588 +                               if (idx > s_idx)
589 +                                       memset(&cb->args[1], 0,
590 +                                              sizeof(cb->args) - sizeof(cb->args[0]));
591 +                               if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
592 +                                                             cb->nlh->nlmsg_seq,
593 +                                                             NFT_MSG_NEWRULE,
594 +                                                             NLM_F_MULTI | NLM_F_APPEND,
595 +                                                             table->afi->family,
596 +                                                             table, chain, rule) < 0)
597 +                                       goto done;
598  
599 -                                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
600 +                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
601  cont:
602 -                                       idx++;
603 -                               }
604 +                               idx++;
605                         }
606                 }
607         }
608 @@ -2238,7 +2232,8 @@ static int nf_tables_getrule(struct net
609         if (IS_ERR(afi))
610                 return PTR_ERR(afi);
611  
612 -       table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
613 +       table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family,
614 +                                      genmask);
615         if (IS_ERR(table))
616                 return PTR_ERR(table);
617  
618 @@ -2323,7 +2318,8 @@ static int nf_tables_newrule(struct net
619         if (IS_ERR(afi))
620                 return PTR_ERR(afi);
621  
622 -       table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
623 +       table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family,
624 +                                      genmask);
625         if (IS_ERR(table))
626                 return PTR_ERR(table);
627  
628 @@ -2362,7 +2358,7 @@ static int nf_tables_newrule(struct net
629                         return PTR_ERR(old_rule);
630         }
631  
632 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
633 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla);
634  
635         n = 0;
636         size = 0;
637 @@ -2495,7 +2491,8 @@ static int nf_tables_delrule(struct net
638         if (IS_ERR(afi))
639                 return PTR_ERR(afi);
640  
641 -       table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
642 +       table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family,
643 +                                      genmask);
644         if (IS_ERR(table))
645                 return PTR_ERR(table);
646  
647 @@ -2506,7 +2503,7 @@ static int nf_tables_delrule(struct net
648                         return PTR_ERR(chain);
649         }
650  
651 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
652 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla);
653  
654         if (chain) {
655                 if (nla[NFTA_RULE_HANDLE]) {
656 @@ -2704,13 +2701,13 @@ static int nft_ctx_init_from_setattr(str
657                 if (afi == NULL)
658                         return -EAFNOSUPPORT;
659  
660 -               table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE],
661 -                                              genmask);
662 +               table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE],
663 +                                              afi->family, genmask);
664                 if (IS_ERR(table))
665                         return PTR_ERR(table);
666         }
667  
668 -       nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
669 +       nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla);
670         return 0;
671  }
672  
673 @@ -2838,7 +2835,7 @@ static int nf_tables_fill_set(struct sk_
674                 goto nla_put_failure;
675  
676         nfmsg = nlmsg_data(nlh);
677 -       nfmsg->nfgen_family     = ctx->afi->family;
678 +       nfmsg->nfgen_family     = ctx->family;
679         nfmsg->version          = NFNETLINK_V0;
680         nfmsg->res_id           = htons(ctx->net->nft.base_seq & 0xffff);
681  
682 @@ -2930,10 +2927,8 @@ static int nf_tables_dump_sets(struct sk
683  {
684         const struct nft_set *set;
685         unsigned int idx, s_idx = cb->args[0];
686 -       struct nft_af_info *afi;
687         struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
688         struct net *net = sock_net(skb->sk);
689 -       int cur_family = cb->args[3];
690         struct nft_ctx *ctx = cb->data, ctx_set;
691  
692         if (cb->args[1])
693 @@ -2942,51 +2937,44 @@ static int nf_tables_dump_sets(struct sk
694         rcu_read_lock();
695         cb->seq = net->nft.base_seq;
696  
697 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
698 -               if (ctx->afi && ctx->afi != afi)
699 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
700 +               if (ctx->family != NFPROTO_UNSPEC &&
701 +                   ctx->family != table->afi->family)
702                         continue;
703  
704 -               if (cur_family) {
705 -                       if (afi->family != cur_family)
706 -                               continue;
707 +               if (ctx->table && ctx->table != table)
708 +                       continue;
709  
710 -                       cur_family = 0;
711 -               }
712 -               list_for_each_entry_rcu(table, &afi->tables, list) {
713 -                       if (ctx->table && ctx->table != table)
714 +               if (cur_table) {
715 +                       if (cur_table != table)
716                                 continue;
717  
718 -                       if (cur_table) {
719 -                               if (cur_table != table)
720 -                                       continue;
721 +                       cur_table = NULL;
722 +               }
723 +               idx = 0;
724 +               list_for_each_entry_rcu(set, &table->sets, list) {
725 +                       if (idx < s_idx)
726 +                               goto cont;
727 +                       if (!nft_is_active(net, set))
728 +                               goto cont;
729  
730 -                               cur_table = NULL;
731 +                       ctx_set = *ctx;
732 +                       ctx_set.table = table;
733 +                       ctx_set.family = table->afi->family;
734 +
735 +                       if (nf_tables_fill_set(skb, &ctx_set, set,
736 +                                              NFT_MSG_NEWSET,
737 +                                              NLM_F_MULTI) < 0) {
738 +                               cb->args[0] = idx;
739 +                               cb->args[2] = (unsigned long) table;
740 +                               goto done;
741                         }
742 -                       idx = 0;
743 -                       list_for_each_entry_rcu(set, &table->sets, list) {
744 -                               if (idx < s_idx)
745 -                                       goto cont;
746 -                               if (!nft_is_active(net, set))
747 -                                       goto cont;
748 -
749 -                               ctx_set = *ctx;
750 -                               ctx_set.table = table;
751 -                               ctx_set.afi = afi;
752 -                               if (nf_tables_fill_set(skb, &ctx_set, set,
753 -                                                      NFT_MSG_NEWSET,
754 -                                                      NLM_F_MULTI) < 0) {
755 -                                       cb->args[0] = idx;
756 -                                       cb->args[2] = (unsigned long) table;
757 -                                       cb->args[3] = afi->family;
758 -                                       goto done;
759 -                               }
760 -                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
761 +                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
762  cont:
763 -                               idx++;
764 -                       }
765 -                       if (s_idx)
766 -                               s_idx = 0;
767 +                       idx++;
768                 }
769 +               if (s_idx)
770 +                       s_idx = 0;
771         }
772         cb->args[1] = 1;
773  done:
774 @@ -3196,11 +3184,12 @@ static int nf_tables_newset(struct net *
775         if (IS_ERR(afi))
776                 return PTR_ERR(afi);
777  
778 -       table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask);
779 +       table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], afi->family,
780 +                                      genmask);
781         if (IS_ERR(table))
782                 return PTR_ERR(table);
783  
784 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
785 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
786  
787         set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask);
788         if (IS_ERR(set)) {
789 @@ -3469,12 +3458,12 @@ static int nft_ctx_init_from_elemattr(st
790         if (IS_ERR(afi))
791                 return PTR_ERR(afi);
792  
793 -       table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE],
794 -                                      genmask);
795 +       table = nf_tables_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE],
796 +                                      afi->family, genmask);
797         if (IS_ERR(table))
798                 return PTR_ERR(table);
799  
800 -       nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
801 +       nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla);
802         return 0;
803  }
804  
805 @@ -3579,7 +3568,6 @@ static int nf_tables_dump_set(struct sk_
806  {
807         struct nft_set_dump_ctx *dump_ctx = cb->data;
808         struct net *net = sock_net(skb->sk);
809 -       struct nft_af_info *afi;
810         struct nft_table *table;
811         struct nft_set *set;
812         struct nft_set_dump_args args;
813 @@ -3591,21 +3579,19 @@ static int nf_tables_dump_set(struct sk_
814         int event;
815  
816         rcu_read_lock();
817 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
818 -               if (afi != dump_ctx->ctx.afi)
819 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
820 +               if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
821 +                   dump_ctx->ctx.family != table->afi->family)
822                         continue;
823  
824 -               list_for_each_entry_rcu(table, &afi->tables, list) {
825 -                       if (table != dump_ctx->ctx.table)
826 -                               continue;
827 +               if (table != dump_ctx->ctx.table)
828 +                       continue;
829  
830 -                       list_for_each_entry_rcu(set, &table->sets, list) {
831 -                               if (set == dump_ctx->set) {
832 -                                       set_found = true;
833 -                                       break;
834 -                               }
835 +               list_for_each_entry_rcu(set, &table->sets, list) {
836 +                       if (set == dump_ctx->set) {
837 +                               set_found = true;
838 +                               break;
839                         }
840 -                       break;
841                 }
842                 break;
843         }
844 @@ -3625,7 +3611,7 @@ static int nf_tables_dump_set(struct sk_
845                 goto nla_put_failure;
846  
847         nfmsg = nlmsg_data(nlh);
848 -       nfmsg->nfgen_family = afi->family;
849 +       nfmsg->nfgen_family = table->afi->family;
850         nfmsg->version      = NFNETLINK_V0;
851         nfmsg->res_id       = htons(net->nft.base_seq & 0xffff);
852  
853 @@ -3727,7 +3713,7 @@ static int nf_tables_fill_setelem_info(s
854                 goto nla_put_failure;
855  
856         nfmsg = nlmsg_data(nlh);
857 -       nfmsg->nfgen_family     = ctx->afi->family;
858 +       nfmsg->nfgen_family     = ctx->family;
859         nfmsg->version          = NFNETLINK_V0;
860         nfmsg->res_id           = htons(ctx->net->nft.base_seq & 0xffff);
861  
862 @@ -3971,7 +3957,7 @@ static int nft_add_set_elem(struct nft_c
863                 list_for_each_entry(binding, &set->bindings, list) {
864                         struct nft_ctx bind_ctx = {
865                                 .net    = ctx->net,
866 -                               .afi    = ctx->afi,
867 +                               .family = ctx->family,
868                                 .table  = ctx->table,
869                                 .chain  = (struct nft_chain *)binding->chain,
870                         };
871 @@ -4521,7 +4507,8 @@ static int nf_tables_newobj(struct net *
872         if (IS_ERR(afi))
873                 return PTR_ERR(afi);
874  
875 -       table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
876 +       table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family,
877 +                                      genmask);
878         if (IS_ERR(table))
879                 return PTR_ERR(table);
880  
881 @@ -4539,7 +4526,7 @@ static int nf_tables_newobj(struct net *
882                 return 0;
883         }
884  
885 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
886 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
887  
888         type = nft_obj_type_get(objtype);
889         if (IS_ERR(type))
890 @@ -4616,7 +4603,6 @@ struct nft_obj_filter {
891  static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
892  {
893         const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
894 -       const struct nft_af_info *afi;
895         const struct nft_table *table;
896         unsigned int idx = 0, s_idx = cb->args[0];
897         struct nft_obj_filter *filter = cb->data;
898 @@ -4631,38 +4617,37 @@ static int nf_tables_dump_obj(struct sk_
899         rcu_read_lock();
900         cb->seq = net->nft.base_seq;
901  
902 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
903 -               if (family != NFPROTO_UNSPEC && family != afi->family)
904 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
905 +               if (family != NFPROTO_UNSPEC && family != table->afi->family)
906                         continue;
907  
908 -               list_for_each_entry_rcu(table, &afi->tables, list) {
909 -                       list_for_each_entry_rcu(obj, &table->objects, list) {
910 -                               if (!nft_is_active(net, obj))
911 -                                       goto cont;
912 -                               if (idx < s_idx)
913 -                                       goto cont;
914 -                               if (idx > s_idx)
915 -                                       memset(&cb->args[1], 0,
916 -                                              sizeof(cb->args) - sizeof(cb->args[0]));
917 -                               if (filter && filter->table &&
918 -                                   strcmp(filter->table, table->name))
919 -                                       goto cont;
920 -                               if (filter &&
921 -                                   filter->type != NFT_OBJECT_UNSPEC &&
922 -                                   obj->ops->type->type != filter->type)
923 -                                       goto cont;
924 +               list_for_each_entry_rcu(obj, &table->objects, list) {
925 +                       if (!nft_is_active(net, obj))
926 +                               goto cont;
927 +                       if (idx < s_idx)
928 +                               goto cont;
929 +                       if (idx > s_idx)
930 +                               memset(&cb->args[1], 0,
931 +                                      sizeof(cb->args) - sizeof(cb->args[0]));
932 +                       if (filter && filter->table &&
933 +                           strcmp(filter->table, table->name))
934 +                               goto cont;
935 +                       if (filter &&
936 +                           filter->type != NFT_OBJECT_UNSPEC &&
937 +                           obj->ops->type->type != filter->type)
938 +                               goto cont;
939  
940 -                               if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
941 -                                                           cb->nlh->nlmsg_seq,
942 -                                                           NFT_MSG_NEWOBJ,
943 -                                                           NLM_F_MULTI | NLM_F_APPEND,
944 -                                                           afi->family, table, obj, reset) < 0)
945 -                                       goto done;
946 +                       if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
947 +                                                   cb->nlh->nlmsg_seq,
948 +                                                   NFT_MSG_NEWOBJ,
949 +                                                   NLM_F_MULTI | NLM_F_APPEND,
950 +                                                   table->afi->family, table,
951 +                                                   obj, reset) < 0)
952 +                               goto done;
953  
954 -                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
955 +                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
956  cont:
957 -                               idx++;
958 -                       }
959 +                       idx++;
960                 }
961         }
962  done:
963 @@ -4749,7 +4734,8 @@ static int nf_tables_getobj(struct net *
964         if (IS_ERR(afi))
965                 return PTR_ERR(afi);
966  
967 -       table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
968 +       table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family,
969 +                                      genmask);
970         if (IS_ERR(table))
971                 return PTR_ERR(table);
972  
973 @@ -4809,7 +4795,8 @@ static int nf_tables_delobj(struct net *
974         if (IS_ERR(afi))
975                 return PTR_ERR(afi);
976  
977 -       table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
978 +       table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family,
979 +                                      genmask);
980         if (IS_ERR(table))
981                 return PTR_ERR(table);
982  
983 @@ -4820,7 +4807,7 @@ static int nf_tables_delobj(struct net *
984         if (obj->use > 0)
985                 return -EBUSY;
986  
987 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
988 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
989  
990         return nft_delobj(&ctx, obj);
991  }
992 @@ -4858,7 +4845,7 @@ static void nf_tables_obj_notify(const s
993                                  struct nft_object *obj, int event)
994  {
995         nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
996 -                      ctx->afi->family, ctx->report, GFP_KERNEL);
997 +                      ctx->family, ctx->report, GFP_KERNEL);
998  }
999  
1000  /*
1001 @@ -5048,7 +5035,7 @@ void nft_flow_table_iterate(struct net *
1002  
1003         rcu_read_lock();
1004         list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
1005 -               list_for_each_entry_rcu(table, &afi->tables, list) {
1006 +               list_for_each_entry_rcu(table, &net->nft.tables, list) {
1007                         list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
1008                                 iter(&flowtable->data, data);
1009                         }
1010 @@ -5096,7 +5083,8 @@ static int nf_tables_newflowtable(struct
1011         if (IS_ERR(afi))
1012                 return PTR_ERR(afi);
1013  
1014 -       table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask);
1015 +       table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE],
1016 +                                      afi->family, genmask);
1017         if (IS_ERR(table))
1018                 return PTR_ERR(table);
1019  
1020 @@ -5113,7 +5101,7 @@ static int nf_tables_newflowtable(struct
1021                 return 0;
1022         }
1023  
1024 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
1025 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
1026  
1027         flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
1028         if (!flowtable)
1029 @@ -5194,7 +5182,8 @@ static int nf_tables_delflowtable(struct
1030         if (IS_ERR(afi))
1031                 return PTR_ERR(afi);
1032  
1033 -       table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask);
1034 +       table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE],
1035 +                                      afi->family, genmask);
1036         if (IS_ERR(table))
1037                 return PTR_ERR(table);
1038  
1039 @@ -5205,7 +5194,7 @@ static int nf_tables_delflowtable(struct
1040         if (flowtable->use > 0)
1041                 return -EBUSY;
1042  
1043 -       nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
1044 +       nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla);
1045  
1046         return nft_delflowtable(&ctx, flowtable);
1047  }
1048 @@ -5274,40 +5263,37 @@ static int nf_tables_dump_flowtable(stru
1049         struct net *net = sock_net(skb->sk);
1050         int family = nfmsg->nfgen_family;
1051         struct nft_flowtable *flowtable;
1052 -       const struct nft_af_info *afi;
1053         const struct nft_table *table;
1054  
1055         rcu_read_lock();
1056         cb->seq = net->nft.base_seq;
1057  
1058 -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
1059 -               if (family != NFPROTO_UNSPEC && family != afi->family)
1060 +       list_for_each_entry_rcu(table, &net->nft.tables, list) {
1061 +               if (family != NFPROTO_UNSPEC && family != table->afi->family)
1062                         continue;
1063  
1064 -               list_for_each_entry_rcu(table, &afi->tables, list) {
1065 -                       list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
1066 -                               if (!nft_is_active(net, flowtable))
1067 -                                       goto cont;
1068 -                               if (idx < s_idx)
1069 -                                       goto cont;
1070 -                               if (idx > s_idx)
1071 -                                       memset(&cb->args[1], 0,
1072 -                                              sizeof(cb->args) - sizeof(cb->args[0]));
1073 -                               if (filter && filter->table[0] &&
1074 -                                   strcmp(filter->table, table->name))
1075 -                                       goto cont;
1076 +               list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
1077 +                       if (!nft_is_active(net, flowtable))
1078 +                               goto cont;
1079 +                       if (idx < s_idx)
1080 +                               goto cont;
1081 +                       if (idx > s_idx)
1082 +                               memset(&cb->args[1], 0,
1083 +                                      sizeof(cb->args) - sizeof(cb->args[0]));
1084 +                       if (filter && filter->table &&
1085 +                           strcmp(filter->table, table->name))
1086 +                               goto cont;
1087  
1088 -                               if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid,
1089 -                                                                 cb->nlh->nlmsg_seq,
1090 -                                                                 NFT_MSG_NEWFLOWTABLE,
1091 -                                                                 NLM_F_MULTI | NLM_F_APPEND,
1092 -                                                                 afi->family, flowtable) < 0)
1093 -                                       goto done;
1094 +                       if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid,
1095 +                                                         cb->nlh->nlmsg_seq,
1096 +                                                         NFT_MSG_NEWFLOWTABLE,
1097 +                                                         NLM_F_MULTI | NLM_F_APPEND,
1098 +                                                         table->afi->family, flowtable) < 0)
1099 +                               goto done;
1100  
1101 -                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1102 +                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1103  cont:
1104 -                               idx++;
1105 -                       }
1106 +                       idx++;
1107                 }
1108         }
1109  done:
1110 @@ -5392,7 +5378,8 @@ static int nf_tables_getflowtable(struct
1111         if (IS_ERR(afi))
1112                 return PTR_ERR(afi);
1113  
1114 -       table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask);
1115 +       table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE],
1116 +                                      afi->family, genmask);
1117         if (IS_ERR(table))
1118                 return PTR_ERR(table);
1119  
1120 @@ -5435,7 +5422,7 @@ static void nf_tables_flowtable_notify(s
1121  
1122         err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
1123                                             ctx->seq, event, 0,
1124 -                                           ctx->afi->family, flowtable);
1125 +                                           ctx->family, flowtable);
1126         if (err < 0) {
1127                 kfree_skb(skb);
1128                 goto err;
1129 @@ -5513,17 +5500,14 @@ static int nf_tables_flowtable_event(str
1130         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1131         struct nft_flowtable *flowtable;
1132         struct nft_table *table;
1133 -       struct nft_af_info *afi;
1134  
1135         if (event != NETDEV_UNREGISTER)
1136                 return 0;
1137  
1138         nfnl_lock(NFNL_SUBSYS_NFTABLES);
1139 -       list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) {
1140 -               list_for_each_entry(table, &afi->tables, list) {
1141 -                       list_for_each_entry(flowtable, &table->flowtables, list) {
1142 -                               nft_flowtable_event(event, dev, flowtable);
1143 -                       }
1144 +       list_for_each_entry(table, &dev_net(dev)->nft.tables, list) {
1145 +               list_for_each_entry(flowtable, &table->flowtables, list) {
1146 +                       nft_flowtable_event(event, dev, flowtable);
1147                 }
1148         }
1149         nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1150 @@ -6549,6 +6533,7 @@ EXPORT_SYMBOL_GPL(nft_data_dump);
1151  static int __net_init nf_tables_init_net(struct net *net)
1152  {
1153         INIT_LIST_HEAD(&net->nft.af_info);
1154 +       INIT_LIST_HEAD(&net->nft.tables);
1155         INIT_LIST_HEAD(&net->nft.commit_list);
1156         net->nft.base_seq = 1;
1157         return 0;
1158 @@ -6585,10 +6570,10 @@ static void __nft_release_afinfo(struct
1159         struct nft_set *set, *ns;
1160         struct nft_ctx ctx = {
1161                 .net    = net,
1162 -               .afi    = afi,
1163 +               .family = afi->family,
1164         };
1165  
1166 -       list_for_each_entry_safe(table, nt, &afi->tables, list) {
1167 +       list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
1168                 list_for_each_entry(chain, &table->chains, list)
1169                         nf_tables_unregister_hook(net, table, chain);
1170                 list_for_each_entry(flowtable, &table->flowtables, list)
1171 --- a/net/netfilter/nf_tables_netdev.c
1172 +++ b/net/netfilter/nf_tables_netdev.c
1173 @@ -107,7 +107,6 @@ static int nf_tables_netdev_event(struct
1174                                   unsigned long event, void *ptr)
1175  {
1176         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1177 -       struct nft_af_info *afi;
1178         struct nft_table *table;
1179         struct nft_chain *chain, *nr;
1180         struct nft_ctx ctx = {
1181 @@ -119,20 +118,18 @@ static int nf_tables_netdev_event(struct
1182                 return NOTIFY_DONE;
1183  
1184         nfnl_lock(NFNL_SUBSYS_NFTABLES);
1185 -       list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) {
1186 -               ctx.afi = afi;
1187 -               if (afi->family != NFPROTO_NETDEV)
1188 +       list_for_each_entry(table, &ctx.net->nft.tables, list) {
1189 +               if (table->afi->family != NFPROTO_NETDEV)
1190                         continue;
1191  
1192 -               list_for_each_entry(table, &afi->tables, list) {
1193 -                       ctx.table = table;
1194 -                       list_for_each_entry_safe(chain, nr, &table->chains, list) {
1195 -                               if (!nft_is_base_chain(chain))
1196 -                                       continue;
1197 +               ctx.family = table->afi->family;
1198 +               ctx.table = table;
1199 +               list_for_each_entry_safe(chain, nr, &table->chains, list) {
1200 +                       if (!nft_is_base_chain(chain))
1201 +                               continue;
1202  
1203 -                               ctx.chain = chain;
1204 -                               nft_netdev_event(event, dev, &ctx);
1205 -                       }
1206 +                       ctx.chain = chain;
1207 +                       nft_netdev_event(event, dev, &ctx);
1208                 }
1209         }
1210         nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1211 --- a/net/netfilter/nft_compat.c
1212 +++ b/net/netfilter/nft_compat.c
1213 @@ -161,7 +161,7 @@ nft_target_set_tgchk_param(struct xt_tgc
1214  {
1215         par->net        = ctx->net;
1216         par->table      = ctx->table->name;
1217 -       switch (ctx->afi->family) {
1218 +       switch (ctx->family) {
1219         case AF_INET:
1220                 entry->e4.ip.proto = proto;
1221                 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
1222 @@ -192,7 +192,7 @@ nft_target_set_tgchk_param(struct xt_tgc
1223         } else {
1224                 par->hook_mask = 0;
1225         }
1226 -       par->family     = ctx->afi->family;
1227 +       par->family     = ctx->family;
1228         par->nft_compat = true;
1229  }
1230  
1231 @@ -282,7 +282,7 @@ nft_target_destroy(const struct nft_ctx
1232         par.net = ctx->net;
1233         par.target = target;
1234         par.targinfo = info;
1235 -       par.family = ctx->afi->family;
1236 +       par.family = ctx->family;
1237         if (par.target->destroy != NULL)
1238                 par.target->destroy(&par);
1239  
1240 @@ -389,7 +389,7 @@ nft_match_set_mtchk_param(struct xt_mtch
1241  {
1242         par->net        = ctx->net;
1243         par->table      = ctx->table->name;
1244 -       switch (ctx->afi->family) {
1245 +       switch (ctx->family) {
1246         case AF_INET:
1247                 entry->e4.ip.proto = proto;
1248                 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
1249 @@ -420,7 +420,7 @@ nft_match_set_mtchk_param(struct xt_mtch
1250         } else {
1251                 par->hook_mask = 0;
1252         }
1253 -       par->family     = ctx->afi->family;
1254 +       par->family     = ctx->family;
1255         par->nft_compat = true;
1256  }
1257  
1258 @@ -503,7 +503,7 @@ __nft_match_destroy(const struct nft_ctx
1259         par.net = ctx->net;
1260         par.match = match;
1261         par.matchinfo = info;
1262 -       par.family = ctx->afi->family;
1263 +       par.family = ctx->family;
1264         if (par.match->destroy != NULL)
1265                 par.match->destroy(&par);
1266  
1267 @@ -733,7 +733,7 @@ nft_match_select_ops(const struct nft_ct
1268  
1269         mt_name = nla_data(tb[NFTA_MATCH_NAME]);
1270         rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV]));
1271 -       family = ctx->afi->family;
1272 +       family = ctx->family;
1273  
1274         /* Re-use the existing match if it's already loaded. */
1275         list_for_each_entry(nft_match, &nft_match_list, head) {
1276 @@ -824,7 +824,7 @@ nft_target_select_ops(const struct nft_c
1277  
1278         tg_name = nla_data(tb[NFTA_TARGET_NAME]);
1279         rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV]));
1280 -       family = ctx->afi->family;
1281 +       family = ctx->family;
1282  
1283         if (strcmp(tg_name, XT_ERROR_TARGET) == 0 ||
1284             strcmp(tg_name, XT_STANDARD_TARGET) == 0 ||
1285 --- a/net/netfilter/nft_ct.c
1286 +++ b/net/netfilter/nft_ct.c
1287 @@ -405,7 +405,7 @@ static int nft_ct_get_init(const struct
1288                 if (tb[NFTA_CT_DIRECTION] == NULL)
1289                         return -EINVAL;
1290  
1291 -               switch (ctx->afi->family) {
1292 +               switch (ctx->family) {
1293                 case NFPROTO_IPV4:
1294                         len = FIELD_SIZEOF(struct nf_conntrack_tuple,
1295                                            src.u3.ip);
1296 @@ -456,7 +456,7 @@ static int nft_ct_get_init(const struct
1297         if (err < 0)
1298                 return err;
1299  
1300 -       err = nf_ct_netns_get(ctx->net, ctx->afi->family);
1301 +       err = nf_ct_netns_get(ctx->net, ctx->family);
1302         if (err < 0)
1303                 return err;
1304  
1305 @@ -550,7 +550,7 @@ static int nft_ct_set_init(const struct
1306         if (err < 0)
1307                 goto err1;
1308  
1309 -       err = nf_ct_netns_get(ctx->net, ctx->afi->family);
1310 +       err = nf_ct_netns_get(ctx->net, ctx->family);
1311         if (err < 0)
1312                 goto err1;
1313  
1314 @@ -564,7 +564,7 @@ err1:
1315  static void nft_ct_get_destroy(const struct nft_ctx *ctx,
1316                                const struct nft_expr *expr)
1317  {
1318 -       nf_ct_netns_put(ctx->net, ctx->afi->family);
1319 +       nf_ct_netns_put(ctx->net, ctx->family);
1320  }
1321  
1322  static void nft_ct_set_destroy(const struct nft_ctx *ctx,
1323 @@ -573,7 +573,7 @@ static void nft_ct_set_destroy(const str
1324         struct nft_ct *priv = nft_expr_priv(expr);
1325  
1326         __nft_ct_set_destroy(ctx, priv);
1327 -       nf_ct_netns_put(ctx->net, ctx->afi->family);
1328 +       nf_ct_netns_put(ctx->net, ctx->family);
1329  }
1330  
1331  static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
1332 @@ -734,7 +734,7 @@ static int nft_ct_helper_obj_init(const
1333         struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1334         struct nf_conntrack_helper *help4, *help6;
1335         char name[NF_CT_HELPER_NAME_LEN];
1336 -       int family = ctx->afi->family;
1337 +       int family = ctx->family;
1338  
1339         if (!tb[NFTA_CT_HELPER_NAME] || !tb[NFTA_CT_HELPER_L4PROTO])
1340                 return -EINVAL;
1341 @@ -753,14 +753,14 @@ static int nft_ct_helper_obj_init(const
1342  
1343         switch (family) {
1344         case NFPROTO_IPV4:
1345 -               if (ctx->afi->family == NFPROTO_IPV6)
1346 +               if (ctx->family == NFPROTO_IPV6)
1347                         return -EINVAL;
1348  
1349                 help4 = nf_conntrack_helper_try_module_get(name, family,
1350                                                            priv->l4proto);
1351                 break;
1352         case NFPROTO_IPV6:
1353 -               if (ctx->afi->family == NFPROTO_IPV4)
1354 +               if (ctx->family == NFPROTO_IPV4)
1355                         return -EINVAL;
1356  
1357                 help6 = nf_conntrack_helper_try_module_get(name, family,
1358 --- a/net/netfilter/nft_flow_offload.c
1359 +++ b/net/netfilter/nft_flow_offload.c
1360 @@ -151,7 +151,7 @@ static int nft_flow_offload_init(const s
1361         priv->flowtable = flowtable;
1362         flowtable->use++;
1363  
1364 -       return nf_ct_netns_get(ctx->net, ctx->afi->family);
1365 +       return nf_ct_netns_get(ctx->net, ctx->family);
1366  }
1367  
1368  static void nft_flow_offload_destroy(const struct nft_ctx *ctx,
1369 @@ -160,7 +160,7 @@ static void nft_flow_offload_destroy(con
1370         struct nft_flow_offload *priv = nft_expr_priv(expr);
1371  
1372         priv->flowtable->use--;
1373 -       nf_ct_netns_put(ctx->net, ctx->afi->family);
1374 +       nf_ct_netns_put(ctx->net, ctx->family);
1375  }
1376  
1377  static int nft_flow_offload_dump(struct sk_buff *skb, const struct nft_expr *expr)
1378 --- a/net/netfilter/nft_log.c
1379 +++ b/net/netfilter/nft_log.c
1380 @@ -112,7 +112,7 @@ static int nft_log_init(const struct nft
1381                 break;
1382         }
1383  
1384 -       err = nf_logger_find_get(ctx->afi->family, li->type);
1385 +       err = nf_logger_find_get(ctx->family, li->type);
1386         if (err < 0)
1387                 goto err1;
1388  
1389 @@ -133,7 +133,7 @@ static void nft_log_destroy(const struct
1390         if (priv->prefix != nft_log_null_prefix)
1391                 kfree(priv->prefix);
1392  
1393 -       nf_logger_put(ctx->afi->family, li->type);
1394 +       nf_logger_put(ctx->family, li->type);
1395  }
1396  
1397  static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr)
1398 --- a/net/netfilter/nft_masq.c
1399 +++ b/net/netfilter/nft_masq.c
1400 @@ -73,7 +73,7 @@ int nft_masq_init(const struct nft_ctx *
1401                 }
1402         }
1403  
1404 -       return nf_ct_netns_get(ctx->net, ctx->afi->family);
1405 +       return nf_ct_netns_get(ctx->net, ctx->family);
1406  }
1407  EXPORT_SYMBOL_GPL(nft_masq_init);
1408  
1409 --- a/net/netfilter/nft_meta.c
1410 +++ b/net/netfilter/nft_meta.c
1411 @@ -341,7 +341,7 @@ static int nft_meta_get_validate(const s
1412         if (priv->key != NFT_META_SECPATH)
1413                 return 0;
1414  
1415 -       switch (ctx->afi->family) {
1416 +       switch (ctx->family) {
1417         case NFPROTO_NETDEV:
1418                 hooks = 1 << NF_NETDEV_INGRESS;
1419                 break;
1420 @@ -372,7 +372,7 @@ int nft_meta_set_validate(const struct n
1421         if (priv->key != NFT_META_PKTTYPE)
1422                 return 0;
1423  
1424 -       switch (ctx->afi->family) {
1425 +       switch (ctx->family) {
1426         case NFPROTO_BRIDGE:
1427                 hooks = 1 << NF_BR_PRE_ROUTING;
1428                 break;
1429 --- a/net/netfilter/nft_nat.c
1430 +++ b/net/netfilter/nft_nat.c
1431 @@ -142,7 +142,7 @@ static int nft_nat_init(const struct nft
1432                 return -EINVAL;
1433  
1434         family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
1435 -       if (family != ctx->afi->family)
1436 +       if (family != ctx->family)
1437                 return -EOPNOTSUPP;
1438  
1439         switch (family) {
1440 --- a/net/netfilter/nft_redir.c
1441 +++ b/net/netfilter/nft_redir.c
1442 @@ -75,7 +75,7 @@ int nft_redir_init(const struct nft_ctx
1443                         return -EINVAL;
1444         }
1445  
1446 -       return nf_ct_netns_get(ctx->net, ctx->afi->family);
1447 +       return nf_ct_netns_get(ctx->net, ctx->family);
1448  }
1449  EXPORT_SYMBOL_GPL(nft_redir_init);
1450