Skip to content

Commit

Permalink
netfilter: nf_tables: do not reduce read-only expressions
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
ummakynes authored and intel-lab-lkp committed Mar 14, 2022
1 parent 7194177 commit 95cc95f
Show file tree
Hide file tree
Showing 31 changed files with 60 additions and 2 deletions.
8 changes: 8 additions & 0 deletions include/net/netfilter/nf_tables.h
Expand Up @@ -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 */
1 change: 1 addition & 0 deletions net/bridge/netfilter/nft_reject_bridge.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/netfilter/nft_dup_ipv4.c
Expand Up @@ -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] = {
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/netfilter/nft_reject_ipv4.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/ipv6/netfilter/nft_dup_ipv6.c
Expand Up @@ -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] = {
Expand Down
1 change: 1 addition & 0 deletions net/ipv6/netfilter/nft_reject_ipv6.c
Expand Up @@ -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 = {
Expand Down
14 changes: 12 additions & 2 deletions net/netfilter/nf_tables_api.c
Expand Up @@ -8260,6 +8260,17 @@ void nf_tables_trans_destroy_flush_work(void)
}
EXPORT_SYMBOL_GPL(nf_tables_trans_destroy_flush_work);

static bool nft_expr_reduce(struct nft_regs_track *track,
const struct nft_expr *expr)
{
if (WARN_ON_ONCE(!expr->ops->reduce))
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)
{
const struct nft_expr *expr, *last;
Expand Down Expand Up @@ -8307,8 +8318,7 @@ static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *cha
nft_rule_for_each_expr(expr, last, rule) {
track.cur = expr;

if (expr->ops->reduce &&
expr->ops->reduce(&track, expr)) {
if (nft_expr_reduce(&track, expr)) {
expr = track.cur;
continue;
}
Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/nft_cmp.c
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
};

Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_compat.c
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_connlimit.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_counter.c
Expand Up @@ -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,
};
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_ct.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_dup_netdev.c
Expand Up @@ -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,
};
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_dynset.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_flow_offload.c
Expand Up @@ -428,6 +428,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 = {
Expand Down
2 changes: 2 additions & 0 deletions net/netfilter/nft_fwd_netdev.c
Expand Up @@ -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 = {
Expand All @@ -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,
};
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_last.c
Expand Up @@ -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 = {
Expand Down
2 changes: 2 additions & 0 deletions net/netfilter/nft_limit.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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 *
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_log.c
Expand Up @@ -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 = {
Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/nft_masq.c
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down
2 changes: 2 additions & 0 deletions net/netfilter/nft_nat.c
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down
2 changes: 2 additions & 0 deletions net/netfilter/nft_objref.c
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 *
Expand Down
2 changes: 2 additions & 0 deletions net/netfilter/nft_queue.c
Expand Up @@ -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 = {
Expand All @@ -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 *
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_quota.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_range.c
Expand Up @@ -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 = {
Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/nft_redir.c
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_reject_inet.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_reject_netdev.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_rt.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_synproxy.c
Expand Up @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/nft_tproxy.c
Expand Up @@ -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 = {
Expand Down

0 comments on commit 95cc95f

Please sign in to comment.