Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: don't call hooks unless needed

With the previous patches in place, a netns nf_hook_list might be empty,
even if e.g. init_net performs filtering.

Thus change nf_hook_thresh to check the hook_list as well before
initializing hook_state and calling nf_hook_slow().

We still make use of static keys; if no netfilter modules are loaded
list is guaranteed to be empty.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
af4610c3 5f6c253e

+11 -18
+11 -18
include/linux/netfilter.h
··· 141 141 142 142 #ifdef HAVE_JUMP_LABEL 143 143 extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; 144 - 145 - static inline bool nf_hook_list_active(struct list_head *hook_list, 146 - u_int8_t pf, unsigned int hook) 147 - { 148 - if (__builtin_constant_p(pf) && 149 - __builtin_constant_p(hook)) 150 - return static_key_false(&nf_hooks_needed[pf][hook]); 151 - 152 - return !list_empty(hook_list); 153 - } 154 - #else 155 - static inline bool nf_hook_list_active(struct list_head *hook_list, 156 - u_int8_t pf, unsigned int hook) 157 - { 158 - return !list_empty(hook_list); 159 - } 160 144 #endif 161 145 162 146 int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state); ··· 161 177 int (*okfn)(struct net *, struct sock *, struct sk_buff *), 162 178 int thresh) 163 179 { 164 - struct list_head *hook_list = &net->nf.hooks[pf][hook]; 180 + struct list_head *hook_list; 165 181 166 - if (nf_hook_list_active(hook_list, pf, hook)) { 182 + #ifdef HAVE_JUMP_LABEL 183 + if (__builtin_constant_p(pf) && 184 + __builtin_constant_p(hook) && 185 + !static_key_false(&nf_hooks_needed[pf][hook])) 186 + return 1; 187 + #endif 188 + 189 + hook_list = &net->nf.hooks[pf][hook]; 190 + 191 + if (!list_empty(hook_list)) { 167 192 struct nf_hook_state state; 168 193 169 194 nf_hook_state_init(&state, hook_list, hook, thresh,