diff options
author | Harald Welte <laforge@netfilter.org> | 2005-08-09 22:43:44 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:36:49 -0400 |
commit | 0ab43f84995f2c2fcc5cc58a9accaa1095e1317f (patch) | |
tree | f58711648f91bbd880fcada7718a2462f0249a78 /net/core | |
parent | 2cc7d5730957c4a3f3659d17d2ba5e06d5581c1f (diff) |
[NETFILTER]: Core changes required by upcoming nfnetlink_queue code
- split netfiler verdict in 16bit verdict and 16bit queue number
- add 'queuenum' argument to nf_queue_outfn_t and its users ip[6]_queue
- move NFNL_SUBSYS_ definitions from enum to #define
- introduce autoloading for nfnetlink subsystem modules
- add MODULE_ALIAS_NFNL_SUBSYS macro
- add nf_unregister_queue_handlers() to register all handlers for a given
nf_queue_outfn_t
- add more verbose DEBUGP macro definition to nfnetlink.c
- make nfnetlink_subsys_register fail if subsys already exists
- add some more comments and debug statements to nfnetlink.c
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/netfilter.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/net/core/netfilter.c b/net/core/netfilter.c index 1ed4f3110421..3e38084ac2bd 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c | |||
@@ -221,7 +221,8 @@ static unsigned int nf_iterate(struct list_head *head, | |||
221 | verdict = elem->hook(hook, skb, indev, outdev, okfn); | 221 | verdict = elem->hook(hook, skb, indev, outdev, okfn); |
222 | if (verdict != NF_ACCEPT) { | 222 | if (verdict != NF_ACCEPT) { |
223 | #ifdef CONFIG_NETFILTER_DEBUG | 223 | #ifdef CONFIG_NETFILTER_DEBUG |
224 | if (unlikely(verdict > NF_MAX_VERDICT)) { | 224 | if (unlikely((verdict & NF_VERDICT_MASK) |
225 | > NF_MAX_VERDICT)) { | ||
225 | NFDEBUG("Evil return from %p(%u).\n", | 226 | NFDEBUG("Evil return from %p(%u).\n", |
226 | elem->hook, hook); | 227 | elem->hook, hook); |
227 | continue; | 228 | continue; |
@@ -239,6 +240,9 @@ int nf_register_queue_handler(int pf, nf_queue_outfn_t outfn, void *data) | |||
239 | { | 240 | { |
240 | int ret; | 241 | int ret; |
241 | 242 | ||
243 | if (pf >= NPROTO) | ||
244 | return -EINVAL; | ||
245 | |||
242 | write_lock_bh(&queue_handler_lock); | 246 | write_lock_bh(&queue_handler_lock); |
243 | if (queue_handler[pf].outfn) | 247 | if (queue_handler[pf].outfn) |
244 | ret = -EBUSY; | 248 | ret = -EBUSY; |
@@ -255,6 +259,9 @@ int nf_register_queue_handler(int pf, nf_queue_outfn_t outfn, void *data) | |||
255 | /* The caller must flush their queue before this */ | 259 | /* The caller must flush their queue before this */ |
256 | int nf_unregister_queue_handler(int pf) | 260 | int nf_unregister_queue_handler(int pf) |
257 | { | 261 | { |
262 | if (pf >= NPROTO) | ||
263 | return -EINVAL; | ||
264 | |||
258 | write_lock_bh(&queue_handler_lock); | 265 | write_lock_bh(&queue_handler_lock); |
259 | queue_handler[pf].outfn = NULL; | 266 | queue_handler[pf].outfn = NULL; |
260 | queue_handler[pf].data = NULL; | 267 | queue_handler[pf].data = NULL; |
@@ -286,6 +293,20 @@ int nf_unregister_queue_rerouter(int pf) | |||
286 | return 0; | 293 | return 0; |
287 | } | 294 | } |
288 | 295 | ||
296 | void nf_unregister_queue_handlers(nf_queue_outfn_t outfn) | ||
297 | { | ||
298 | int pf; | ||
299 | |||
300 | write_lock_bh(&queue_handler_lock); | ||
301 | for (pf = 0; pf < NPROTO; pf++) { | ||
302 | if (queue_handler[pf].outfn == outfn) { | ||
303 | queue_handler[pf].outfn = NULL; | ||
304 | queue_handler[pf].data = NULL; | ||
305 | } | ||
306 | } | ||
307 | write_unlock_bh(&queue_handler_lock); | ||
308 | } | ||
309 | |||
289 | /* | 310 | /* |
290 | * Any packet that leaves via this function must come back | 311 | * Any packet that leaves via this function must come back |
291 | * through nf_reinject(). | 312 | * through nf_reinject(). |
@@ -295,7 +316,8 @@ static int nf_queue(struct sk_buff **skb, | |||
295 | int pf, unsigned int hook, | 316 | int pf, unsigned int hook, |
296 | struct net_device *indev, | 317 | struct net_device *indev, |
297 | struct net_device *outdev, | 318 | struct net_device *outdev, |
298 | int (*okfn)(struct sk_buff *)) | 319 | int (*okfn)(struct sk_buff *), |
320 | unsigned int queuenum) | ||
299 | { | 321 | { |
300 | int status; | 322 | int status; |
301 | struct nf_info *info; | 323 | struct nf_info *info; |
@@ -347,7 +369,8 @@ static int nf_queue(struct sk_buff **skb, | |||
347 | if (queue_rerouter[pf].save) | 369 | if (queue_rerouter[pf].save) |
348 | queue_rerouter[pf].save(*skb, info); | 370 | queue_rerouter[pf].save(*skb, info); |
349 | 371 | ||
350 | status = queue_handler[pf].outfn(*skb, info, queue_handler[pf].data); | 372 | status = queue_handler[pf].outfn(*skb, info, queuenum, |
373 | queue_handler[pf].data); | ||
351 | 374 | ||
352 | if (status >= 0 && queue_rerouter[pf].reroute) | 375 | if (status >= 0 && queue_rerouter[pf].reroute) |
353 | status = queue_rerouter[pf].reroute(skb, info); | 376 | status = queue_rerouter[pf].reroute(skb, info); |
@@ -397,9 +420,10 @@ next_hook: | |||
397 | } else if (verdict == NF_DROP) { | 420 | } else if (verdict == NF_DROP) { |
398 | kfree_skb(*pskb); | 421 | kfree_skb(*pskb); |
399 | ret = -EPERM; | 422 | ret = -EPERM; |
400 | } else if (verdict == NF_QUEUE) { | 423 | } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { |
401 | NFDEBUG("nf_hook: Verdict = QUEUE.\n"); | 424 | NFDEBUG("nf_hook: Verdict = QUEUE.\n"); |
402 | if (!nf_queue(pskb, elem, pf, hook, indev, outdev, okfn)) | 425 | if (!nf_queue(pskb, elem, pf, hook, indev, outdev, okfn, |
426 | verdict >> NF_VERDICT_BITS)) | ||
403 | goto next_hook; | 427 | goto next_hook; |
404 | } | 428 | } |
405 | unlock: | 429 | unlock: |
@@ -456,14 +480,15 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, | |||
456 | info->okfn, INT_MIN); | 480 | info->okfn, INT_MIN); |
457 | } | 481 | } |
458 | 482 | ||
459 | switch (verdict) { | 483 | switch (verdict & NF_VERDICT_MASK) { |
460 | case NF_ACCEPT: | 484 | case NF_ACCEPT: |
461 | info->okfn(skb); | 485 | info->okfn(skb); |
462 | break; | 486 | break; |
463 | 487 | ||
464 | case NF_QUEUE: | 488 | case NF_QUEUE: |
465 | if (!nf_queue(&skb, elem, info->pf, info->hook, | 489 | if (!nf_queue(&skb, elem, info->pf, info->hook, |
466 | info->indev, info->outdev, info->okfn)) | 490 | info->indev, info->outdev, info->okfn, |
491 | verdict >> NF_VERDICT_BITS)) | ||
467 | goto next_hook; | 492 | goto next_hook; |
468 | break; | 493 | break; |
469 | } | 494 | } |
@@ -613,6 +638,7 @@ EXPORT_SYMBOL(nf_reinject); | |||
613 | EXPORT_SYMBOL(nf_setsockopt); | 638 | EXPORT_SYMBOL(nf_setsockopt); |
614 | EXPORT_SYMBOL(nf_unregister_hook); | 639 | EXPORT_SYMBOL(nf_unregister_hook); |
615 | EXPORT_SYMBOL(nf_unregister_queue_handler); | 640 | EXPORT_SYMBOL(nf_unregister_queue_handler); |
641 | EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers); | ||
616 | EXPORT_SYMBOL_GPL(nf_register_queue_rerouter); | 642 | EXPORT_SYMBOL_GPL(nf_register_queue_rerouter); |
617 | EXPORT_SYMBOL_GPL(nf_unregister_queue_rerouter); | 643 | EXPORT_SYMBOL_GPL(nf_unregister_queue_rerouter); |
618 | EXPORT_SYMBOL(nf_unregister_sockopt); | 644 | EXPORT_SYMBOL(nf_unregister_sockopt); |