Commit 62472bcefb56ae9c3a6be3284949ce758656cdec

Authored by Patrick McHardy
Committed by Pablo Neira Ayuso
1 parent a36e901cf6

netfilter: nf_tables: restore context for expression destructors

In order to fix set destruction notifications and get rid of unnecessary
members in private data structures, pass the context to expressions'
destructor functions again.

In order to do so, replace various members in the nft_rule_trans structure
by the full context.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 7 changed files with 31 additions and 32 deletions Side-by-side Diff

include/net/netfilter/nf_tables.h
... ... @@ -289,7 +289,8 @@
289 289 int (*init)(const struct nft_ctx *ctx,
290 290 const struct nft_expr *expr,
291 291 const struct nlattr * const tb[]);
292   - void (*destroy)(const struct nft_expr *expr);
  292 + void (*destroy)(const struct nft_ctx *ctx,
  293 + const struct nft_expr *expr);
293 294 int (*dump)(struct sk_buff *skb,
294 295 const struct nft_expr *expr);
295 296 int (*validate)(const struct nft_ctx *ctx,
296 297  
297 298  
298 299  
... ... @@ -343,19 +344,13 @@
343 344 * struct nft_rule_trans - nf_tables rule update in transaction
344 345 *
345 346 * @list: used internally
  347 + * @ctx: rule context
346 348 * @rule: rule that needs to be updated
347   - * @chain: chain that this rule belongs to
348   - * @table: table for which this chain applies
349   - * @nlh: netlink header of the message that contain this update
350   - * @family: family expressesed as AF_*
351 349 */
352 350 struct nft_rule_trans {
353 351 struct list_head list;
  352 + struct nft_ctx ctx;
354 353 struct nft_rule *rule;
355   - const struct nft_chain *chain;
356   - const struct nft_table *table;
357   - const struct nlmsghdr *nlh;
358   - u8 family;
359 354 };
360 355  
361 356 static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
net/netfilter/nf_tables_api.c
... ... @@ -1253,10 +1253,11 @@
1253 1253 return err;
1254 1254 }
1255 1255  
1256   -static void nf_tables_expr_destroy(struct nft_expr *expr)
  1256 +static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
  1257 + struct nft_expr *expr)
1257 1258 {
1258 1259 if (expr->ops->destroy)
1259   - expr->ops->destroy(expr);
  1260 + expr->ops->destroy(ctx, expr);
1260 1261 module_put(expr->ops->type->owner);
1261 1262 }
1262 1263  
... ... @@ -1536,7 +1537,8 @@
1536 1537 return err;
1537 1538 }
1538 1539  
1539   -static void nf_tables_rule_destroy(struct nft_rule *rule)
  1540 +static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
  1541 + struct nft_rule *rule)
1540 1542 {
1541 1543 struct nft_expr *expr;
1542 1544  
... ... @@ -1546,7 +1548,7 @@
1546 1548 */
1547 1549 expr = nft_expr_first(rule);
1548 1550 while (expr->ops && expr != nft_expr_last(rule)) {
1549   - nf_tables_expr_destroy(expr);
  1551 + nf_tables_expr_destroy(ctx, expr);
1550 1552 expr = nft_expr_next(expr);
1551 1553 }
1552 1554 kfree(rule);
1553 1555  
... ... @@ -1565,11 +1567,8 @@
1565 1567 if (rupd == NULL)
1566 1568 return NULL;
1567 1569  
1568   - rupd->chain = ctx->chain;
1569   - rupd->table = ctx->table;
  1570 + rupd->ctx = *ctx;
1570 1571 rupd->rule = rule;
1571   - rupd->family = ctx->afi->family;
1572   - rupd->nlh = ctx->nlh;
1573 1572 list_add_tail(&rupd->list, &ctx->net->nft.commit_list);
1574 1573  
1575 1574 return rupd;
... ... @@ -1721,7 +1720,7 @@
1721 1720 kfree(repl);
1722 1721 }
1723 1722 err2:
1724   - nf_tables_rule_destroy(rule);
  1723 + nf_tables_rule_destroy(&ctx, rule);
1725 1724 err1:
1726 1725 for (i = 0; i < n; i++) {
1727 1726 if (info[i].ops != NULL)
... ... @@ -1831,10 +1830,10 @@
1831 1830 */
1832 1831 if (nft_rule_is_active(net, rupd->rule)) {
1833 1832 nft_rule_clear(net, rupd->rule);
1834   - nf_tables_rule_notify(skb, rupd->nlh, rupd->table,
1835   - rupd->chain, rupd->rule,
1836   - NFT_MSG_NEWRULE, 0,
1837   - rupd->family);
  1833 + nf_tables_rule_notify(skb, rupd->ctx.nlh,
  1834 + rupd->ctx.table, rupd->ctx.chain,
  1835 + rupd->rule, NFT_MSG_NEWRULE, 0,
  1836 + rupd->ctx.afi->family);
1838 1837 list_del(&rupd->list);
1839 1838 kfree(rupd);
1840 1839 continue;
1841 1840  
... ... @@ -1842,9 +1841,10 @@
1842 1841  
1843 1842 /* This rule is in the past, get rid of it */
1844 1843 list_del_rcu(&rupd->rule->list);
1845   - nf_tables_rule_notify(skb, rupd->nlh, rupd->table, rupd->chain,
  1844 + nf_tables_rule_notify(skb, rupd->ctx.nlh,
  1845 + rupd->ctx.table, rupd->ctx.chain,
1846 1846 rupd->rule, NFT_MSG_DELRULE, 0,
1847   - rupd->family);
  1847 + rupd->ctx.afi->family);
1848 1848 }
1849 1849  
1850 1850 /* Make sure we don't see any packet traversing old rules */
... ... @@ -1852,7 +1852,7 @@
1852 1852  
1853 1853 /* Now we can safely release unused old rules */
1854 1854 list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) {
1855   - nf_tables_rule_destroy(rupd->rule);
  1855 + nf_tables_rule_destroy(&rupd->ctx, rupd->rule);
1856 1856 list_del(&rupd->list);
1857 1857 kfree(rupd);
1858 1858 }
... ... @@ -1881,7 +1881,7 @@
1881 1881 synchronize_rcu();
1882 1882  
1883 1883 list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) {
1884   - nf_tables_rule_destroy(rupd->rule);
  1884 + nf_tables_rule_destroy(&rupd->ctx, rupd->rule);
1885 1885 list_del(&rupd->list);
1886 1886 kfree(rupd);
1887 1887 }
net/netfilter/nft_compat.c
... ... @@ -192,7 +192,7 @@
192 192 }
193 193  
194 194 static void
195   -nft_target_destroy(const struct nft_expr *expr)
  195 +nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
196 196 {
197 197 struct xt_target *target = expr->ops->data;
198 198  
... ... @@ -379,7 +379,7 @@
379 379 }
380 380  
381 381 static void
382   -nft_match_destroy(const struct nft_expr *expr)
  382 +nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
383 383 {
384 384 struct xt_match *match = expr->ops->data;
385 385  
net/netfilter/nft_ct.c
... ... @@ -321,7 +321,8 @@
321 321 return 0;
322 322 }
323 323  
324   -static void nft_ct_destroy(const struct nft_expr *expr)
  324 +static void nft_ct_destroy(const struct nft_ctx *ctx,
  325 + const struct nft_expr *expr)
325 326 {
326 327 struct nft_ct *priv = nft_expr_priv(expr);
327 328  
net/netfilter/nft_immediate.c
... ... @@ -70,7 +70,8 @@
70 70 return err;
71 71 }
72 72  
73   -static void nft_immediate_destroy(const struct nft_expr *expr)
  73 +static void nft_immediate_destroy(const struct nft_ctx *ctx,
  74 + const struct nft_expr *expr)
74 75 {
75 76 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
76 77 return nft_data_uninit(&priv->data, nft_dreg_to_type(priv->dreg));
net/netfilter/nft_log.c
... ... @@ -74,7 +74,8 @@
74 74 return 0;
75 75 }
76 76  
77   -static void nft_log_destroy(const struct nft_expr *expr)
  77 +static void nft_log_destroy(const struct nft_ctx *ctx,
  78 + const struct nft_expr *expr)
78 79 {
79 80 struct nft_log *priv = nft_expr_priv(expr);
80 81  
net/netfilter/nft_lookup.c
... ... @@ -89,7 +89,8 @@
89 89 return 0;
90 90 }
91 91  
92   -static void nft_lookup_destroy(const struct nft_expr *expr)
  92 +static void nft_lookup_destroy(const struct nft_ctx *ctx,
  93 + const struct nft_expr *expr)
93 94 {
94 95 struct nft_lookup *priv = nft_expr_priv(expr);
95 96