All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wang Jian <lark@linux.net.cn>
To: netfilter-devel@lists.netfilter.org
Subject: Re: Netfilter and Kernel Threads
Date: Fri, 01 Apr 2005 09:54:10 +0800	[thread overview]
Message-ID: <20050401094856.01ED.LARK@linux.net.cn> (raw)
In-Reply-To: <OFDADA6776.7D6B0627-ONC1256F95.0043FD45-C1256F95.00443200@ch.ibm.com>

Hi Roland Wehage,

Kernel thread can only be created in process context, not in interrupt
context. mod_init() is called in process context but example_hook() is not.

On Wed, 26 Jan 2005 13:24:52 +0100, Roland Wehage <RWE@zurich.ibm.com> wrote:

> Hello,
> 
> I hope you can help me, you would do me a great favour...
> 
> My question is about Linux Netfilter (I am using Kernel 2.6.10):
> 
> Background:
> I am writing a Netfilter module and a driver for a hardware packet
> classifier. So the filtiring should take place for every packet that passes
> one of the following Netfilterhooks:
> -NF_IP_FORWARD
> -NF_IP_LOCAL_IN
> -NF_IP_LOCAL_OUT
> When a packet is send to the classifier (by using a PCI-Bus), the module
> can only expect a certain number returned (for example: 0 = Accept packet,
> 1 = Drop...). So I am not getting back any packet ID or something like
> this.
> 
> Because it can happen, that Netfilter calls this module faster than the
> classifier is able to do the filtering, I thought of creating a kernel
> thread for each packet:
> 
> for example:
> 
> unsigned int example_hook(unsigned int hooknum, struct sk_buff **skb, ...)
> {
>       ...
>       thread_id = kernel_thread(thread_code, NULL, CLONE_KERNEL);
>       ...
> }
> 
> After forwarding the packet to the Classifier, the thread is set asleep and
> waits for being woken up. After the PCI-Bus returned an interrupt the
> thread is woken up.
> My problem is that I cannot create threads in this architecture.
> 
> My test code is something like this:
> 
> ...
> 
> static wait_que_head_t wq;
> static int thread_id = 0;
> static DECLARE_COMPLETION(on_exit);
> statir int first = 1;
> 
> ...
> 
> static int thread_code(void *data)
> {
>       daemonize("ThisThread");
>       allow_signal(SIGTERM);
>       thread_id = 0;
>       complete_and_exit(&on_exit, 0);
> }
> 
> unsigned int example_hook(unsigned int hooknum, struct sk_buff **skb, ...)
> {
>       if(first)//only to guarantee that only the first call will create a
> thread, to show that the system crashes
>       //whenever kernel_thread() is called
>       {
>             first = 0;
>             thread_id = kernel_thread(thread_code, NULL, CLONE_KERNEL);
>             if(thread_id)
>                   kill_proc(thread_id, SIGTERM, 1);
>             wait_for_completion(&on_exit);
>       }
>       return NF_ACCEPT;
> }
> 
> static struct nf_hook_ops example_ops =
> {
>       .hook = example_hook,
>       .pf = PF_INET,
>       .hooknum = NF_IP_LOCAL_IN,
>       .priority = -1,
> };
> 
> static int __init mod_init(void)
> {
>       init_waitqueue_head(&wq);
>       if(nf_register_hook(&example_ops) < 0)
>             return 1;
>       return 0;
> }
> 
> static void __exit mod_exit(void)
> {
>       nf_unregister_hook(&example_ops);
> }
> 
> My problem is, that the system crashes when I load this module and I just
> do not know why.
> 
> The following construction works, but is not what I need, I cannot see the
> main difference, why this works and the construction above not:
> 
> ...
> 
> static wait_que_head_t wq;
> static int thread_id = 0;
> static DECLARE_COMPLETION(on_exit);
> ...
> 
> static int thread_code(void *data)
> {
>       daemonize("ThisThread");
>       allow_signal(SIGTERM);
>       thread_id = 0;
>       complete_and_exit(&on_exit, 0);
> }
> 
> unsigned int example_hook(unsigned int hooknum, struct sk_buff **skb, ...)
> {
>       return NF_ACCEPT;
> }
> 
> static struct nf_hook_ops example_ops =
> {
>       .hook = example_hook,
>       .pf = PF_INET,
>       .hooknum = NF_IP_LOCAL_IN,
>       .priority = -1,
> };
> 
> static int __init mod_init(void)
> {
>       init_waitqueue_head(&wq);
>       thread_id = kernel_thread(thread_code, NULL, CLONE_KERNEL);
>       if(thread_id)
>             kill_proc(thread_id, SIGTERM, 1);
>       wait_for_completion(&on_exit);
>       if(nf_register_hook(&example_ops) < 0)
>             return 1;
>       return 0;
> }
> 
> static void __exit mod_exit(void)
> {
>       nf_unregister_hook(&example_ops);
> }
> 
> You would do me a grait favour, if you would help me. Thanks a lot!
> 
> With regards,
> 
> Roland Wehage.
> 



-- 
  lark

  reply	other threads:[~2005-04-01  1:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-26 12:24 Netfilter and Kernel Threads Roland Wehage
2005-04-01  1:54 ` Wang Jian [this message]
2005-04-01  2:00   ` Re[2]: " Wang Jian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050401094856.01ED.LARK@linux.net.cn \
    --to=lark@linux.net.cn \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.