All of lore.kernel.org
 help / color / mirror / Atom feed
* Netfilter and Kernel Threads
@ 2005-01-26 12:24 Roland Wehage
  2005-04-01  1:54 ` Wang Jian
  0 siblings, 1 reply; 3+ messages in thread
From: Roland Wehage @ 2005-01-26 12:24 UTC (permalink / raw)
  To: netfilter-devel

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.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Netfilter and Kernel Threads
  2005-01-26 12:24 Netfilter and Kernel Threads Roland Wehage
@ 2005-04-01  1:54 ` Wang Jian
  2005-04-01  2:00   ` Re[2]: " Wang Jian
  0 siblings, 1 reply; 3+ messages in thread
From: Wang Jian @ 2005-04-01  1:54 UTC (permalink / raw)
  To: netfilter-devel

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re[2]: Netfilter and Kernel Threads
  2005-04-01  1:54 ` Wang Jian
@ 2005-04-01  2:00   ` Wang Jian
  0 siblings, 0 replies; 3+ messages in thread
From: Wang Jian @ 2005-04-01  2:00 UTC (permalink / raw)
  To: netfilter-devel

Hi list,

Sorry for this mail. I switched mail client to thread mode and the time
order is in mess. I didn't notice that and replied to the 'newest' mail.
I just realized I am so stupid after I hit Send button.

On Fri, 01 Apr 2005 09:54:10 +0800, Wang Jian <lark@linux.net.cn> wrote:

> 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
> 



-- 
  lark

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-04-01  2:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-26 12:24 Netfilter and Kernel Threads Roland Wehage
2005-04-01  1:54 ` Wang Jian
2005-04-01  2:00   ` Re[2]: " Wang Jian

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.