dev_queue_xmit随后使用tun / tap设备返回NET_XMIT_CN

时间:2016-10-13 21:45:16

标签: networking linux-kernel kernel-module netfilter tun

我有一个用户空间程序,它构建自己的数据包(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设备吗?有没有比这更简单的方法?

如果我应该提供任何额外的细节或澄清一些事情,请告诉我。

0 个答案:

没有答案