Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 222440b4 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_tables: handle meta/lookup with direct call



Currently nft uses inlined variants for common operations
such as 'ip saddr 1.2.3.4' instead of an indirect call.

Also handle meta get operations and lookups without indirect call,
both are builtin.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent ecbcd689
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -71,4 +71,11 @@ extern struct nft_set_type nft_set_hash_fast_type;
extern struct nft_set_type nft_set_rbtree_type;
extern struct nft_set_type nft_set_bitmap_type;

struct nft_expr;
struct nft_regs;
struct nft_pktinfo;
void nft_meta_get_eval(const struct nft_expr *expr,
		       struct nft_regs *regs, const struct nft_pktinfo *pkt);
void nft_lookup_eval(const struct nft_expr *expr,
		     struct nft_regs *regs, const struct nft_pktinfo *pkt);
#endif /* _NET_NF_TABLES_CORE_H */
+15 −1
Original line number Diff line number Diff line
@@ -120,6 +120,20 @@ struct nft_jumpstack {
	struct nft_rule	*const *rules;
};

static void expr_call_ops_eval(const struct nft_expr *expr,
			       struct nft_regs *regs,
			       struct nft_pktinfo *pkt)
{
	unsigned long e = (unsigned long)expr->ops->eval;

	if (e == (unsigned long)nft_meta_get_eval)
		nft_meta_get_eval(expr, regs, pkt);
	else if (e == (unsigned long)nft_lookup_eval)
		nft_lookup_eval(expr, regs, pkt);
	else
		expr->ops->eval(expr, regs, pkt);
}

unsigned int
nft_do_chain(struct nft_pktinfo *pkt, void *priv)
{
@@ -153,7 +167,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
				nft_cmp_fast_eval(expr, &regs);
			else if (expr->ops != &nft_payload_fast_ops ||
				 !nft_payload_fast_eval(expr, &regs, pkt))
				expr->ops->eval(expr, &regs, pkt);
				expr_call_ops_eval(expr, &regs, pkt);

			if (regs.verdict.code != NFT_CONTINUE)
				break;
+3 −3
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ struct nft_lookup {
	struct nft_set_binding		binding;
};

static void nft_lookup_eval(const struct nft_expr *expr,
void nft_lookup_eval(const struct nft_expr *expr,
		     struct nft_regs *regs,
		     const struct nft_pktinfo *pkt)
{
+3 −3
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
#include "../bridge/br_private.h"
#endif

static void nft_meta_get_eval(const struct nft_expr *expr,
void nft_meta_get_eval(const struct nft_expr *expr,
		       struct nft_regs *regs,
		       const struct nft_pktinfo *pkt)
{