netfilter: nf_tables: do not reduce read-only expressions
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 14 Mar 2022 17:23:00 +0000 (18:23 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 19 Mar 2022 23:29:46 +0000 (00:29 +0100)
Skip register tracking for expressions that perform read-only operations
on the registers. Define and use a cookie pointer NFT_REDUCE_READONLY to
avoid defining stubs for these expressions.

This patch re-enables register tracking which was disabled in ed5f85d42290
("netfilter: nf_tables: disable register tracking"). Follow up patches
add remaining register tracking for existing expressions.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
31 files changed:
include/net/netfilter/nf_tables.h
net/bridge/netfilter/nft_reject_bridge.c
net/ipv4/netfilter/nft_dup_ipv4.c
net/ipv4/netfilter/nft_reject_ipv4.c
net/ipv6/netfilter/nft_dup_ipv6.c
net/ipv6/netfilter/nft_reject_ipv6.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_cmp.c
net/netfilter/nft_compat.c
net/netfilter/nft_connlimit.c
net/netfilter/nft_counter.c
net/netfilter/nft_ct.c
net/netfilter/nft_dup_netdev.c
net/netfilter/nft_dynset.c
net/netfilter/nft_flow_offload.c
net/netfilter/nft_fwd_netdev.c
net/netfilter/nft_last.c
net/netfilter/nft_limit.c
net/netfilter/nft_log.c
net/netfilter/nft_masq.c
net/netfilter/nft_nat.c
net/netfilter/nft_objref.c
net/netfilter/nft_queue.c
net/netfilter/nft_quota.c
net/netfilter/nft_range.c
net/netfilter/nft_redir.c
net/netfilter/nft_reject_inet.c
net/netfilter/nft_reject_netdev.c
net/netfilter/nft_rt.c
net/netfilter/nft_synproxy.c
net/netfilter/nft_tproxy.c

index c4c0861deac12ad00edc6a4f50f96c5eba7cf0b3..edabfb9e97ce4a61fa466b0bf47016d7a46711a6 100644 (file)
@@ -1633,4 +1633,12 @@ static inline struct nftables_pernet *nft_pernet(const struct net *net)
        return net_generic(net, nf_tables_net_id);
 }
 
+#define __NFT_REDUCE_READONLY  1UL
+#define NFT_REDUCE_READONLY    (void *)__NFT_REDUCE_READONLY
+
+static inline bool nft_reduce_is_readonly(const struct nft_expr *expr)
+{
+       return expr->ops->reduce == NFT_REDUCE_READONLY;
+}
+
 #endif /* _NET_NF_TABLES_H */
index fbf858ddec352183b5c7dcb6e2611ca29a50845f..71b54fed7263df62342102fc6effc25e6be17d52 100644 (file)
@@ -185,6 +185,7 @@ static const struct nft_expr_ops nft_reject_bridge_ops = {
        .init           = nft_reject_init,
        .dump           = nft_reject_dump,
        .validate       = nft_reject_bridge_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_reject_bridge_type __read_mostly = {
index aeb631760eb9edf3d80e437a1b5471f1a9c98c6b..0bcd6aee60008c6742f942d7a465516504da5a34 100644 (file)
@@ -75,6 +75,7 @@ static const struct nft_expr_ops nft_dup_ipv4_ops = {
        .eval           = nft_dup_ipv4_eval,
        .init           = nft_dup_ipv4_init,
        .dump           = nft_dup_ipv4_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nla_policy nft_dup_ipv4_policy[NFTA_DUP_MAX + 1] = {
index 55fc23a8f7a70611ff39af92dd1e2586f6f00aeb..6cb213bb7256a8438068f61b8b8fe02a68a285c3 100644 (file)
@@ -45,6 +45,7 @@ static const struct nft_expr_ops nft_reject_ipv4_ops = {
        .init           = nft_reject_init,
        .dump           = nft_reject_dump,
        .validate       = nft_reject_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_reject_ipv4_type __read_mostly = {
index 3a00d95e964e9462862095754ff259b67324e5f0..70a405b4006f9681e49bb9265c56ea569e802f53 100644 (file)
@@ -73,6 +73,7 @@ static const struct nft_expr_ops nft_dup_ipv6_ops = {
        .eval           = nft_dup_ipv6_eval,
        .init           = nft_dup_ipv6_init,
        .dump           = nft_dup_ipv6_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nla_policy nft_dup_ipv6_policy[NFTA_DUP_MAX + 1] = {
index ed69c768797ec6f9f0a0c582d25908c298cc18da..5c61294f410ee1ec00364c159534c46481a72803 100644 (file)
@@ -46,6 +46,7 @@ static const struct nft_expr_ops nft_reject_ipv6_ops = {
        .init           = nft_reject_init,
        .dump           = nft_reject_dump,
        .validate       = nft_reject_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_reject_ipv6_type __read_mostly = {
index e37ac88efa0a68ff7db72f93f44ec9cb0d95f8de..6a10042243eb1a397dae64297f40a9fa7ec6ce5c 100644 (file)
@@ -8290,7 +8290,16 @@ EXPORT_SYMBOL_GPL(nf_tables_trans_destroy_flush_work);
 static bool nft_expr_reduce(struct nft_regs_track *track,
                            const struct nft_expr *expr)
 {
-       return false;
+       if (!expr->ops->reduce) {
+               pr_warn_once("missing reduce for expression %s ",
+                            expr->ops->type->name);
+               return false;
+       }
+
+       if (nft_reduce_is_readonly(expr))
+               return false;
+
+       return expr->ops->reduce(track, expr);
 }
 
 static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *chain)
index 917072af09df904b285d8eb7873693bc34d38c4c..6528f76ca29ec38e9c96c1f8ece6d7b7ea4dbb46 100644 (file)
@@ -193,6 +193,7 @@ static const struct nft_expr_ops nft_cmp_ops = {
        .eval           = nft_cmp_eval,
        .init           = nft_cmp_init,
        .dump           = nft_cmp_dump,
+       .reduce         = NFT_REDUCE_READONLY,
        .offload        = nft_cmp_offload,
 };
 
@@ -269,6 +270,7 @@ const struct nft_expr_ops nft_cmp_fast_ops = {
        .eval           = NULL, /* inlined */
        .init           = nft_cmp_fast_init,
        .dump           = nft_cmp_fast_dump,
+       .reduce         = NFT_REDUCE_READONLY,
        .offload        = nft_cmp_fast_offload,
 };
 
@@ -359,6 +361,7 @@ const struct nft_expr_ops nft_cmp16_fast_ops = {
        .eval           = NULL, /* inlined */
        .init           = nft_cmp16_fast_init,
        .dump           = nft_cmp16_fast_dump,
+       .reduce         = NFT_REDUCE_READONLY,
        .offload        = nft_cmp16_fast_offload,
 };
 
index 5a46d8289d1d9a53eeecc257f3c5f69aaa6c4050..c16172427622e4f87eaf82f110b1994f3f92c800 100644 (file)
@@ -871,6 +871,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
        ops->dump = nft_target_dump;
        ops->validate = nft_target_validate;
        ops->data = target;
+       ops->reduce = NFT_REDUCE_READONLY;
 
        if (family == NFPROTO_BRIDGE)
                ops->eval = nft_target_eval_bridge;
index 3362417ebfdb7a2f1ff305ae36af49d039b72dd4..9de1462e4ac4fd803f925ace0f45a3a52ce7997a 100644 (file)
@@ -257,6 +257,7 @@ static const struct nft_expr_ops nft_connlimit_ops = {
        .destroy_clone  = nft_connlimit_destroy_clone,
        .dump           = nft_connlimit_dump,
        .gc             = nft_connlimit_gc,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_connlimit_type __read_mostly = {
index f179e8c3b0ca7747791a5785407f35b81c697c34..da9083605a61ad1107612e05f5c528cc3f945177 100644 (file)
@@ -293,6 +293,7 @@ static const struct nft_expr_ops nft_counter_ops = {
        .destroy_clone  = nft_counter_destroy,
        .dump           = nft_counter_dump,
        .clone          = nft_counter_clone,
+       .reduce         = NFT_REDUCE_READONLY,
        .offload        = nft_counter_offload,
        .offload_stats  = nft_counter_offload_stats,
 };
index 9c7472af9e4a136ff7f88c1acabd0902df98b2a8..1ec9a7e96e59fcf062219d4eccd7942ba474bdc4 100644 (file)
@@ -785,6 +785,7 @@ static const struct nft_expr_ops nft_notrack_ops = {
        .type           = &nft_notrack_type,
        .size           = NFT_EXPR_SIZE(0),
        .eval           = nft_notrack_eval,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_notrack_type __read_mostly = {
index 5b5c607fbf83f020f1b8929c4fa7a36d6a20471a..63507402716d1ad813f98c78190923434fec82ae 100644 (file)
@@ -79,6 +79,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = {
        .eval           = nft_dup_netdev_eval,
        .init           = nft_dup_netdev_init,
        .dump           = nft_dup_netdev_dump,
+       .reduce         = NFT_REDUCE_READONLY,
        .offload        = nft_dup_netdev_offload,
        .offload_action = nft_dup_netdev_offload_action,
 };
index 87f3af4645d9c75697b95adc7ad0a2c2fd01d593..22f70b543fa24fb5a673972bd80a4868922e6717 100644 (file)
@@ -413,6 +413,7 @@ static const struct nft_expr_ops nft_dynset_ops = {
        .activate       = nft_dynset_activate,
        .deactivate     = nft_dynset_deactivate,
        .dump           = nft_dynset_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 struct nft_expr_type nft_dynset_type __read_mostly = {
index 731b5d87ef453c8fb75e28ba4f0d0c0ec88caf38..900d48c810a12654e011f3693252c0b04f493d5b 100644 (file)
@@ -441,6 +441,7 @@ static const struct nft_expr_ops nft_flow_offload_ops = {
        .destroy        = nft_flow_offload_destroy,
        .validate       = nft_flow_offload_validate,
        .dump           = nft_flow_offload_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_flow_offload_type __read_mostly = {
index 08e7a289738e0588013f8769367f33d2a4570252..7c5876dc9ff2b51f4d2b0124b39b99419c5c8885 100644 (file)
@@ -217,6 +217,7 @@ static const struct nft_expr_ops nft_fwd_neigh_netdev_ops = {
        .init           = nft_fwd_neigh_init,
        .dump           = nft_fwd_neigh_dump,
        .validate       = nft_fwd_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nft_expr_ops nft_fwd_netdev_ops = {
@@ -226,6 +227,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = {
        .init           = nft_fwd_netdev_init,
        .dump           = nft_fwd_netdev_dump,
        .validate       = nft_fwd_validate,
+       .reduce         = NFT_REDUCE_READONLY,
        .offload        = nft_fwd_netdev_offload,
        .offload_action = nft_fwd_netdev_offload_action,
 };
index 4f745a409d347c231c30cb88aba840009295e231..43d0d4aadb1f65fd908dc38b16aae256a8a86778 100644 (file)
@@ -120,6 +120,7 @@ static const struct nft_expr_ops nft_last_ops = {
        .destroy        = nft_last_destroy,
        .clone          = nft_last_clone,
        .dump           = nft_last_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 struct nft_expr_type nft_last_type __read_mostly = {
index a726b623963de486a89178f11f657256d0cc06e8..d4a6cf3cd697895ce82f6aaf89de8095782bfdd8 100644 (file)
@@ -225,6 +225,7 @@ static const struct nft_expr_ops nft_limit_pkts_ops = {
        .destroy        = nft_limit_pkts_destroy,
        .clone          = nft_limit_pkts_clone,
        .dump           = nft_limit_pkts_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static void nft_limit_bytes_eval(const struct nft_expr *expr,
@@ -279,6 +280,7 @@ static const struct nft_expr_ops nft_limit_bytes_ops = {
        .dump           = nft_limit_bytes_dump,
        .clone          = nft_limit_bytes_clone,
        .destroy        = nft_limit_bytes_destroy,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nft_expr_ops *
index 54f6c2035e84d7fad1a90ac5a476f42e8601db1d..0e13c003f0c151a78f62e41f6b177c781a24a20b 100644 (file)
@@ -290,6 +290,7 @@ static const struct nft_expr_ops nft_log_ops = {
        .init           = nft_log_init,
        .destroy        = nft_log_destroy,
        .dump           = nft_log_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_log_type __read_mostly = {
index 9953e8053753642ee64706563c3280a61a4ee2cb..2a0adc497bbb4dc5aa399e1b124ca5f677c6bceb 100644 (file)
@@ -129,6 +129,7 @@ static const struct nft_expr_ops nft_masq_ipv4_ops = {
        .destroy        = nft_masq_ipv4_destroy,
        .dump           = nft_masq_dump,
        .validate       = nft_masq_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_masq_ipv4_type __read_mostly = {
@@ -175,6 +176,7 @@ static const struct nft_expr_ops nft_masq_ipv6_ops = {
        .destroy        = nft_masq_ipv6_destroy,
        .dump           = nft_masq_dump,
        .validate       = nft_masq_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_masq_ipv6_type __read_mostly = {
@@ -230,6 +232,7 @@ static const struct nft_expr_ops nft_masq_inet_ops = {
        .destroy        = nft_masq_inet_destroy,
        .dump           = nft_masq_dump,
        .validate       = nft_masq_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_masq_inet_type __read_mostly = {
index be1595d6979d8107098921a9cc6675c38b53e3b2..4394df4bc99b4cb64e8c0b7900623c7a43570ddd 100644 (file)
@@ -317,6 +317,7 @@ static const struct nft_expr_ops nft_nat_ops = {
        .destroy        = nft_nat_destroy,
        .dump           = nft_nat_dump,
        .validate       = nft_nat_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_nat_type __read_mostly = {
@@ -346,6 +347,7 @@ static const struct nft_expr_ops nft_nat_inet_ops = {
        .destroy        = nft_nat_destroy,
        .dump           = nft_nat_dump,
        .validate       = nft_nat_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_inet_nat_type __read_mostly = {
index 94b2327e71dc485dbfdd517b7860ce33c170e90c..5d8d91b3904db1e64db7f87be02709bac5639bdc 100644 (file)
@@ -91,6 +91,7 @@ static const struct nft_expr_ops nft_objref_ops = {
        .activate       = nft_objref_activate,
        .deactivate     = nft_objref_deactivate,
        .dump           = nft_objref_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 struct nft_objref_map {
@@ -204,6 +205,7 @@ static const struct nft_expr_ops nft_objref_map_ops = {
        .deactivate     = nft_objref_map_deactivate,
        .destroy        = nft_objref_map_destroy,
        .dump           = nft_objref_map_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nft_expr_ops *
index 9ba1de51ac0708c223490bd732e192539227f200..15e4b7640dc00041dab7ddaebd26c20d26235753 100644 (file)
@@ -164,6 +164,7 @@ static const struct nft_expr_ops nft_queue_ops = {
        .eval           = nft_queue_eval,
        .init           = nft_queue_init,
        .dump           = nft_queue_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nft_expr_ops nft_queue_sreg_ops = {
@@ -172,6 +173,7 @@ static const struct nft_expr_ops nft_queue_sreg_ops = {
        .eval           = nft_queue_sreg_eval,
        .init           = nft_queue_sreg_init,
        .dump           = nft_queue_sreg_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static const struct nft_expr_ops *
index f394a0b562f66f36a3b63066471125de5bcb2709..d7db57ed3bc10f2b4388d6399458e9e09a5494db 100644 (file)
@@ -254,6 +254,7 @@ static const struct nft_expr_ops nft_quota_ops = {
        .destroy        = nft_quota_destroy,
        .clone          = nft_quota_clone,
        .dump           = nft_quota_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_quota_type __read_mostly = {
index e4a1c44d7f513ef978e3e5b10e8f171d0c47899e..66f77484c227907255aea6f32524c5bedc4fc83d 100644 (file)
@@ -140,6 +140,7 @@ static const struct nft_expr_ops nft_range_ops = {
        .eval           = nft_range_eval,
        .init           = nft_range_init,
        .dump           = nft_range_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 struct nft_expr_type nft_range_type __read_mostly = {
index ba09890dddb50d0fbd43843c6bfa06b9c6f704e6..5086adfe731cb6418c52e9c11b3f8ef3d82c1fbd 100644 (file)
@@ -134,6 +134,7 @@ static const struct nft_expr_ops nft_redir_ipv4_ops = {
        .destroy        = nft_redir_ipv4_destroy,
        .dump           = nft_redir_dump,
        .validate       = nft_redir_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_redir_ipv4_type __read_mostly = {
@@ -183,6 +184,7 @@ static const struct nft_expr_ops nft_redir_ipv6_ops = {
        .destroy        = nft_redir_ipv6_destroy,
        .dump           = nft_redir_dump,
        .validate       = nft_redir_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_redir_ipv6_type __read_mostly = {
@@ -225,6 +227,7 @@ static const struct nft_expr_ops nft_redir_inet_ops = {
        .destroy        = nft_redir_inet_destroy,
        .dump           = nft_redir_dump,
        .validate       = nft_redir_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_redir_inet_type __read_mostly = {
index 554caf967baa20b322a65bff4ab6d8e82515a55e..973fa31a9dd6cd55ef3c67d4b3f9970fe9816db9 100644 (file)
@@ -80,6 +80,7 @@ static const struct nft_expr_ops nft_reject_inet_ops = {
        .init           = nft_reject_init,
        .dump           = nft_reject_dump,
        .validate       = nft_reject_inet_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_reject_inet_type __read_mostly = {
index 61cd8c4ac385b3415af1311ffc3f78e856af546d..7865cd8b11bb6a3bbab23e92344e9b4cfc07804c 100644 (file)
@@ -159,6 +159,7 @@ static const struct nft_expr_ops nft_reject_netdev_ops = {
        .init           = nft_reject_init,
        .dump           = nft_reject_dump,
        .validate       = nft_reject_netdev_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_reject_netdev_type __read_mostly = {
index bcd01a63e38f1bdb423cc9be816d3612beb533e6..71931ec917219c125eb67d2a545041317ba2232e 100644 (file)
@@ -191,6 +191,7 @@ static const struct nft_expr_ops nft_rt_get_ops = {
        .init           = nft_rt_get_init,
        .dump           = nft_rt_get_dump,
        .validate       = nft_rt_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 struct nft_expr_type nft_rt_type __read_mostly = {
index 1133e06f3c40eb4cd4b1c13ed6a7e4dd6734f3c5..6cf9a04fbfe23b52ee7064c3ed72333221c1cc46 100644 (file)
@@ -288,6 +288,7 @@ static const struct nft_expr_ops nft_synproxy_ops = {
        .dump           = nft_synproxy_dump,
        .type           = &nft_synproxy_type,
        .validate       = nft_synproxy_validate,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_synproxy_type __read_mostly = {
index b5b09a902c7acd9122808da5b80ae16ff245812f..801f013971dfaf4633395fb7c70f512f34928646 100644 (file)
@@ -320,6 +320,7 @@ static const struct nft_expr_ops nft_tproxy_ops = {
        .init           = nft_tproxy_init,
        .destroy        = nft_tproxy_destroy,
        .dump           = nft_tproxy_dump,
+       .reduce         = NFT_REDUCE_READONLY,
 };
 
 static struct nft_expr_type nft_tproxy_type __read_mostly = {