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

netfilter: move nf_reinject into nfnetlink_queue modules

No need to keep this in the core, move it to the nfnetlink_queue module.
nf_reroute is moved too, there were no other callers.

Signed-off-by: Florian Westphal <fw@strlen.de>

+142 -145
-1
include/linux/netfilter.h
··· 370 370 u_int8_t protocol, unsigned short family); 371 371 int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl, 372 372 bool strict, unsigned short family); 373 - int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry); 374 373 375 374 #include <net/flow.h> 376 375
-1
include/net/netfilter/nf_queue.h
··· 35 35 36 36 void nf_register_queue_handler(const struct nf_queue_handler *qh); 37 37 void nf_unregister_queue_handler(void); 38 - void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); 39 38 40 39 bool nf_queue_entry_get_refs(struct nf_queue_entry *entry); 41 40 void nf_queue_entry_free(struct nf_queue_entry *entry);
-106
net/netfilter/nf_queue.c
··· 248 248 return 0; 249 249 } 250 250 EXPORT_SYMBOL_GPL(nf_queue); 251 - 252 - static unsigned int nf_iterate(struct sk_buff *skb, 253 - struct nf_hook_state *state, 254 - const struct nf_hook_entries *hooks, 255 - unsigned int *index) 256 - { 257 - const struct nf_hook_entry *hook; 258 - unsigned int verdict, i = *index; 259 - 260 - while (i < hooks->num_hook_entries) { 261 - hook = &hooks->hooks[i]; 262 - repeat: 263 - verdict = nf_hook_entry_hookfn(hook, skb, state); 264 - if (verdict != NF_ACCEPT) { 265 - *index = i; 266 - if (verdict != NF_REPEAT) 267 - return verdict; 268 - goto repeat; 269 - } 270 - i++; 271 - } 272 - 273 - *index = i; 274 - return NF_ACCEPT; 275 - } 276 - 277 - static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum) 278 - { 279 - switch (pf) { 280 - #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE 281 - case NFPROTO_BRIDGE: 282 - return rcu_dereference(net->nf.hooks_bridge[hooknum]); 283 - #endif 284 - case NFPROTO_IPV4: 285 - return rcu_dereference(net->nf.hooks_ipv4[hooknum]); 286 - case NFPROTO_IPV6: 287 - return rcu_dereference(net->nf.hooks_ipv6[hooknum]); 288 - default: 289 - WARN_ON_ONCE(1); 290 - return NULL; 291 - } 292 - 293 - return NULL; 294 - } 295 - 296 - /* Caller must hold rcu read-side lock */ 297 - void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 298 - { 299 - const struct nf_hook_entry *hook_entry; 300 - const struct nf_hook_entries *hooks; 301 - struct sk_buff *skb = entry->skb; 302 - const struct net *net; 303 - unsigned int i; 304 - int err; 305 - u8 pf; 306 - 307 - net = entry->state.net; 308 - pf = entry->state.pf; 309 - 310 - hooks = nf_hook_entries_head(net, pf, entry->state.hook); 311 - 312 - i = entry->hook_index; 313 - if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) { 314 - kfree_skb(skb); 315 - nf_queue_entry_free(entry); 316 - return; 317 - } 318 - 319 - hook_entry = &hooks->hooks[i]; 320 - 321 - /* Continue traversal iff userspace said ok... */ 322 - if (verdict == NF_REPEAT) 323 - verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state); 324 - 325 - if (verdict == NF_ACCEPT) { 326 - if (nf_reroute(skb, entry) < 0) 327 - verdict = NF_DROP; 328 - } 329 - 330 - if (verdict == NF_ACCEPT) { 331 - next_hook: 332 - ++i; 333 - verdict = nf_iterate(skb, &entry->state, hooks, &i); 334 - } 335 - 336 - switch (verdict & NF_VERDICT_MASK) { 337 - case NF_ACCEPT: 338 - case NF_STOP: 339 - local_bh_disable(); 340 - entry->state.okfn(entry->state.net, entry->state.sk, skb); 341 - local_bh_enable(); 342 - break; 343 - case NF_QUEUE: 344 - err = nf_queue(skb, &entry->state, i, verdict); 345 - if (err == 1) 346 - goto next_hook; 347 - break; 348 - case NF_STOLEN: 349 - break; 350 - default: 351 - kfree_skb(skb); 352 - } 353 - 354 - nf_queue_entry_free(entry); 355 - } 356 - EXPORT_SYMBOL(nf_reinject);
-37
net/netfilter/utils.c
··· 179 179 } 180 180 EXPORT_SYMBOL_GPL(nf_route); 181 181 182 - static int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry) 183 - { 184 - #ifdef CONFIG_INET 185 - const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); 186 - 187 - if (entry->state.hook == NF_INET_LOCAL_OUT) { 188 - const struct iphdr *iph = ip_hdr(skb); 189 - 190 - if (!(iph->tos == rt_info->tos && 191 - skb->mark == rt_info->mark && 192 - iph->daddr == rt_info->daddr && 193 - iph->saddr == rt_info->saddr)) 194 - return ip_route_me_harder(entry->state.net, entry->state.sk, 195 - skb, RTN_UNSPEC); 196 - } 197 - #endif 198 - return 0; 199 - } 200 - 201 - int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry) 202 - { 203 - const struct nf_ipv6_ops *v6ops; 204 - int ret = 0; 205 - 206 - switch (entry->state.pf) { 207 - case AF_INET: 208 - ret = nf_ip_reroute(skb, entry); 209 - break; 210 - case AF_INET6: 211 - v6ops = rcu_dereference(nf_ipv6_ops); 212 - if (v6ops) 213 - ret = v6ops->reroute(skb, entry); 214 - break; 215 - } 216 - return ret; 217 - } 218 - 219 182 /* Only get and check the lengths, not do any hop-by-hop stuff. */ 220 183 int nf_ip6_check_hbh_len(struct sk_buff *skb, u32 *plen) 221 184 {