Skip to content

Commit 10870dd

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nf_tables: add direct calls for all builtin expressions
With CONFIG_RETPOLINE its faster to add an if (ptr == &foo_func) check and and use direct calls for all the built-in expressions. ~15% improvement in pathological cases. checkpatch doesn't like the X macro due to the embedded return statement, but the macro has a very limited scope so I don't think its a problem. I would like to avoid bugs of the form If (e->ops->eval == (unsigned long)nft_foo_eval) nft_bar_eval(); and open-coded if ()/else if()/else cascade, thus the macro. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 4d44175 commit 10870dd

File tree

10 files changed

+55
-31
lines changed

10 files changed

+55
-31
lines changed

include/net/netfilter/nf_tables_core.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@ struct nft_regs;
8080
struct nft_pktinfo;
8181
void nft_meta_get_eval(const struct nft_expr *expr,
8282
struct nft_regs *regs, const struct nft_pktinfo *pkt);
83+
void nft_cmp_eval(const struct nft_expr *expr,
84+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
8385
void nft_lookup_eval(const struct nft_expr *expr,
8486
struct nft_regs *regs, const struct nft_pktinfo *pkt);
87+
void nft_payload_eval(const struct nft_expr *expr,
88+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
89+
void nft_immediate_eval(const struct nft_expr *expr,
90+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
91+
void nft_bitwise_eval(const struct nft_expr *expr,
92+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
93+
void nft_range_eval(const struct nft_expr *expr,
94+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
95+
void nft_byteorder_eval(const struct nft_expr *expr,
96+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
97+
void nft_dynset_eval(const struct nft_expr *expr,
98+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
99+
void nft_rt_get_eval(const struct nft_expr *expr,
100+
struct nft_regs *regs, const struct nft_pktinfo *pkt);
85101
#endif /* _NET_NF_TABLES_CORE_H */

net/netfilter/nf_tables_core.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,25 @@ static void expr_call_ops_eval(const struct nft_expr *expr,
124124
struct nft_regs *regs,
125125
struct nft_pktinfo *pkt)
126126
{
127+
#ifdef CONFIG_RETPOLINE
127128
unsigned long e = (unsigned long)expr->ops->eval;
128-
129-
if (e == (unsigned long)nft_meta_get_eval)
130-
nft_meta_get_eval(expr, regs, pkt);
131-
else if (e == (unsigned long)nft_lookup_eval)
132-
nft_lookup_eval(expr, regs, pkt);
133-
else
134-
expr->ops->eval(expr, regs, pkt);
129+
#define X(e, fun) \
130+
do { if ((e) == (unsigned long)(fun)) \
131+
return fun(expr, regs, pkt); } while (0)
132+
133+
X(e, nft_payload_eval);
134+
X(e, nft_cmp_eval);
135+
X(e, nft_meta_get_eval);
136+
X(e, nft_lookup_eval);
137+
X(e, nft_range_eval);
138+
X(e, nft_immediate_eval);
139+
X(e, nft_byteorder_eval);
140+
X(e, nft_dynset_eval);
141+
X(e, nft_rt_get_eval);
142+
X(e, nft_bitwise_eval);
143+
#undef X
144+
#endif /* CONFIG_RETPOLINE */
145+
expr->ops->eval(expr, regs, pkt);
135146
}
136147

137148
unsigned int

net/netfilter/nft_bitwise.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ struct nft_bitwise {
2525
struct nft_data xor;
2626
};
2727

28-
static void nft_bitwise_eval(const struct nft_expr *expr,
29-
struct nft_regs *regs,
30-
const struct nft_pktinfo *pkt)
28+
void nft_bitwise_eval(const struct nft_expr *expr,
29+
struct nft_regs *regs, const struct nft_pktinfo *pkt)
3130
{
3231
const struct nft_bitwise *priv = nft_expr_priv(expr);
3332
const u32 *src = &regs->data[priv->sreg];

net/netfilter/nft_byteorder.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ struct nft_byteorder {
2626
u8 size;
2727
};
2828

29-
static void nft_byteorder_eval(const struct nft_expr *expr,
30-
struct nft_regs *regs,
31-
const struct nft_pktinfo *pkt)
29+
void nft_byteorder_eval(const struct nft_expr *expr,
30+
struct nft_regs *regs,
31+
const struct nft_pktinfo *pkt)
3232
{
3333
const struct nft_byteorder *priv = nft_expr_priv(expr);
3434
u32 *src = &regs->data[priv->sreg];

net/netfilter/nft_cmp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ struct nft_cmp_expr {
2424
enum nft_cmp_ops op:8;
2525
};
2626

27-
static void nft_cmp_eval(const struct nft_expr *expr,
28-
struct nft_regs *regs,
29-
const struct nft_pktinfo *pkt)
27+
void nft_cmp_eval(const struct nft_expr *expr,
28+
struct nft_regs *regs,
29+
const struct nft_pktinfo *pkt)
3030
{
3131
const struct nft_cmp_expr *priv = nft_expr_priv(expr);
3232
int d;

net/netfilter/nft_dynset.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,8 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
6262
return NULL;
6363
}
6464

65-
static void nft_dynset_eval(const struct nft_expr *expr,
66-
struct nft_regs *regs,
67-
const struct nft_pktinfo *pkt)
65+
void nft_dynset_eval(const struct nft_expr *expr,
66+
struct nft_regs *regs, const struct nft_pktinfo *pkt)
6867
{
6968
const struct nft_dynset *priv = nft_expr_priv(expr);
7069
struct nft_set *set = priv->set;

net/netfilter/nft_immediate.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#include <net/netfilter/nf_tables_core.h>
1818
#include <net/netfilter/nf_tables.h>
1919

20-
static void nft_immediate_eval(const struct nft_expr *expr,
21-
struct nft_regs *regs,
22-
const struct nft_pktinfo *pkt)
20+
void nft_immediate_eval(const struct nft_expr *expr,
21+
struct nft_regs *regs,
22+
const struct nft_pktinfo *pkt)
2323
{
2424
const struct nft_immediate_expr *priv = nft_expr_priv(expr);
2525

net/netfilter/nft_payload.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, u8 offset, u8 len)
7070
return skb_copy_bits(skb, offset + mac_off, dst_u8, len) == 0;
7171
}
7272

73-
static void nft_payload_eval(const struct nft_expr *expr,
74-
struct nft_regs *regs,
75-
const struct nft_pktinfo *pkt)
73+
void nft_payload_eval(const struct nft_expr *expr,
74+
struct nft_regs *regs,
75+
const struct nft_pktinfo *pkt)
7676
{
7777
const struct nft_payload *priv = nft_expr_priv(expr);
7878
const struct sk_buff *skb = pkt->skb;

net/netfilter/nft_range.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ struct nft_range_expr {
2323
enum nft_range_ops op:8;
2424
};
2525

26-
static void nft_range_eval(const struct nft_expr *expr,
27-
struct nft_regs *regs,
28-
const struct nft_pktinfo *pkt)
26+
void nft_range_eval(const struct nft_expr *expr,
27+
struct nft_regs *regs, const struct nft_pktinfo *pkt)
2928
{
3029
const struct nft_range_expr *priv = nft_expr_priv(expr);
3130
int d1, d2;

net/netfilter/nft_rt.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ static u16 get_tcpmss(const struct nft_pktinfo *pkt, const struct dst_entry *skb
5353
return mtu - minlen;
5454
}
5555

56-
static void nft_rt_get_eval(const struct nft_expr *expr,
57-
struct nft_regs *regs,
58-
const struct nft_pktinfo *pkt)
56+
void nft_rt_get_eval(const struct nft_expr *expr,
57+
struct nft_regs *regs,
58+
const struct nft_pktinfo *pkt)
5959
{
6060
const struct nft_rt *priv = nft_expr_priv(expr);
6161
const struct sk_buff *skb = pkt->skb;

0 commit comments

Comments
 (0)