我有一个用户空间程序,它构建自己的数据包(App,UDP,IP)并将write()
构建到TUN设备。该数据包被我自己的Netfilter模块截获,它会检查它收到的数据包是否是我们想要处理的数据包。然后我的Netfilter模块将skb_clone()
原始skb
并创建一个响应数据包,我填写一些数据以返回到用户空间程序。要发送回复,我使用dev_queue_xmit()
。它随机返回NET_XMIT_CN
,即使我刚刚创建了一个新的TUN设备,并且没有其他流量通过。如果我继续执行用户空间程序(向TUN设备发送新数据包),最终TUN设备将响应,但不一致。我似乎无法追查它为什么表现得如此不规律。
基本上我使用TUN设备作为从用户空间到内核空间进行通信的机制,反之亦然。
这是我的用户空间应用:
tun_fd = tun_alloc(dev_name);
packet = ... /* Construct request...*/
nwrite = write(tun_fd, packet, packet_len);
...
unsigned recv_buf[1500];
int received = 0;
while (!received) {
nread = read(tun_fd, recv_buf, 1500);
...
}
...
close(tun_fd);
这是我的Netfilter模块:
static struct nf_hook_ops nfho;
static int __init my_hook(void)
{
nfho.hook = hook_func;
nfho.hooknum = 0;
nfho.hook = PF_INET;
nfho.hook = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
}
unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
struct sk_buff *clone_skb = skb_clone(skb, GFP_KERNEL):
...
/*
* Check if packet is for us.
* Check IP & UDP header, etc
* If so, parse request, put together response clone_skb
*/
...
if ((err = dev_queue_xmit(clone_skb)) != 0) {
printk(....)
/* Either it return 0 (success) or 2, meaning NET_XMIT_CN */
}
return NF_STOLEN;
}
我似乎无法弄清楚这种行为。我误用了TUN设备吗?有没有比这更简单的方法?
如果我应该提供任何额外的细节或澄清一些事情,请告诉我。