发送 SKB 以从内核传输 space

Sending SKB's for transmission from kernel space

我目前正在编写一个修改数据包有效载荷的内核模块,作为一种学习经验。我已经完成数据包修改,但现在我想在原始数据包之后发送这个新的修改数据包(我不想丢弃原始数据包)。我似乎找不到发送 SKB 进行传输的内核函数。我试过 dev_queue_xmit(nskb) 但这会导致内核恐慌,我也试过 skb->next = nskb 但那什么都不做。我必须实施 SKB 列表处理吗?自从这篇文章 seems to be outdated 以来,我不确定该怎么做。

编辑:

所以我能够在调用 dev_queue_xmit(nskb) 时修复内核恐慌,我不小心执行了 dev_queue_xmit(skb),这会删除 skb 并导致网络过滤器出现恐慌。现在的问题是一切正常,但我没有看到重复的数据包被发送出去,也没有第二个数据包被发送的痕迹。机器上的 TCPDump 没有看到任何东西,目标上的 TPCDump 也没有看到任何东西,以下是我的代码。

unsigned int in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
    struct sk_buff *nskb = skb_copy(skb, GFP_KERNEL);
    /* Various other variables not relevant to the problem */
    __u32 saddr, daddr;
    saddr = ntohl(iph->saddr);
    if (saddr == ipToInt(10,0,2,12) || saddr == ipToInt(10,0,2,13)) {
        /*For loop that saves the payload contents into a variable */

        /* Here is where the problem is, 
        I have this if statement to prevent a feedback loop
        then if the ip matches, I call dev_queue_xmit(nskb) 
        which is supposed to send out sk_buff's, but TCPDump doesn't
        show anything on any computer */
        if (saddr == ipToInt(10,0,2,13)) {
            dev_queue_xmit(nskb);
        }

        /* Rest of the code that isn't relevant to sending packets */
   }
   return NF_ACCEPT;
}

我的网络设置如下,它是 3 个 Ubuntu 服务器 VM,所有这些都是从主机通过 SSH 连接到(如果是 macOS,我现在还不知道) .计算机 运行 上述内核模块双向欺骗其他两个虚拟机。其他两个 VM 然后通过 netcat 会话相互交谈。我希望当我使用 ip 10.0.2.13 从 VM 发送一条消息时,10.0.2.12 会看到两条相同的消息。我知道确认号码事故会中断连接,但我不明白。这 3 台计算机上的 TCPDump 除了应该发送的数据包之外没有显示任何内容。

到目前为止,我已经尝试了 dev_queue_xmit(nskb) 以及 nskb->dev->netdev_ops->ndo_start_xmit(nskb, skb->dev)

据我所知,dev_queue_xmit() 是正确的发送程序。问题是你要发送的skb是怎么准备的?当内核恐慌发生时,还给我们 dmesg 的调用跟踪。你设置skb->dev?

我想通了,skb_copy 不会复制 skb 的以太网 header,所以发送的数据包永远不会到达目的地。