1
votes

I am writing a kernel module which needs to do some packet filtering work at the IP layer. What I need to do is intercept all IP packets, and on some outgoing packets, I need to withhold them for a small amount of time (like a few dozen milliseconds) for analysis before sending them on their way.

I've got the kernel module up and running, at the moment it accepts all incoming packets and returns NF_QUEUE on all outgoing packets. I can then pick up those packets using libnetfilter in userspace (like with a Python script and NetfilterQueue) but the problem is that the Python library takes a queue number, and my kernel module queues up the packets in queue #0. How do I configure that?!

This is what my kernel module's outgoing packet hook looks like (cobbled up from various sources):

static struct nf_hook_ops nfho_send;

unsigned int hook_send_func(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
  return NF_QUEUE;
}

/* in init_module() */

nfho_send.hook = hook_send_func;
nfho_send.hooknum = NF_INET_POST_ROUTING;
nfho_send.pf = NFPROTO_IPV4;
nfho_send.priority = NF_IP_PRI_LAST;
nf_register_hook(&nfho_send);

Where do I specify which queue the packets will end up on? What is the significance of queue numbers? I can't be processing random stray packets queued by another hook than mine, is that already done by default?

Thanks! Also, I am using Linux 3.x.

1

1 Answers

2
votes

Use the NF_QUEUE_NR(x) macro. You pass it a single argument (the queue number), and it will build your return value for you. Specifically, it will left-shift the queue number by 16 bits and then AND it with NF_QUEUE.

If you're interested, the implementation is in include/uapi/linux/netfilter.h