【问题标题】:How to get sk_buff_head in kernel driver?如何在内核驱动程序中获取 sk_buff_head?
【发布时间】:2018-02-18 14:32:55
【问题描述】:

我目前正在编写一个网络驱动程序,并且在传输函数中我想修改套接字缓冲区队列。因此我需要获得sk_buff_head 的锁,但是从套接​​字缓冲区到头部的链接在几年前就被删除了。

如何从ndo_start_xmit(struct sk_buff *skb, net_device *dev) 访问sk_buff_head

我正在使用当前的 linux 内核 4.15.3。

背景

我修改了虚拟网络设备的现有驱动程序以实现依赖于帧顺序的分片,因此第二个分片必须直接在第一个分片之后发送。它适用于第 2 层帧。

因此我连接了start_xmit函数,简化后看起来像这样:

static spinlock_t xmit_lock;
start_xmit(struct sk_buff *skb, struct net_device *dev)
{

    [...]

    if(skb->len > TRESHHOLD) {
        second_skb = do_fragmentation(skb);
    }

    [...]

    spin_lock_bh(&xmit_lock);

    if(second_skb) {
         second_skb->next = skb->next;
         second_skb->prev = skb;
         skb->next = second_skb;
    }

    ret = dev_queue_xmit(skb);

    spin_lock_bh(&xmit_lock);
}

所以我想达到两个 skb 都按照这个顺序发送,不应该有发送的帧通过这个驱动程序。这在使用 ping 洪水模式或 iperf 与 UDP 时有效,但有时它会与使用 TCP 连接的 iperf 混淆。然后,有一些情况是顺序混乱的。

为了解决这个问题,我认为我需要 skb 的“真正”队列锁,因此我需要 sk_buff_head

【问题讨论】:

  • 您使用的是 v4 内核吗?
  • 是的,抱歉,已添加此信息
  • 您能否明确说明您正在实施的具体内容,最好是一些代码?例如你是想重新实现__dev_queue_xmitnetpoll_send_skb_on_dev的效果吗?
  • 对不起,我想现在我想要达到的内容更容易理解了。

标签: c linux-kernel network-programming linux-device-driver


【解决方案1】:

要正确执行此操作,您需要在私有数据结构中设置本地锁:

例如

struct my_protocol {
    spinlock_t lock;
}

在开发过程中使用alloc_netdev() 设置它->open(通常在分配例程中完成),然后您可以使用netdev_priv 访问该结构并保持锁定。

【讨论】:

  • 但是我的驱动程序中只有一些锁,但我想获得 skb 队列的锁,这样就没有其他东西可以修改队列了。此外,我可以使用 skb 函数来修改队列。
  • aaaah 你想获取给定队列的 skb_buff_head,那么你可以使用 container_of。让我看看我是否可以修改我的答案
  • 是的,我想访问当前 skb 所在的队列
  • 但是你怎么知道 skb 没有被 net core 出列呢?
  • 嗯,我不知道。但是没有传输队列吗?我正在编写一个虚拟网络设备驱动程序并使用物理或底层设备传输一个。我想获得队列以确保在它之后直接传输另一个新的 skb。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-14
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
相关资源
最近更新 更多