【发布时间】: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_xmit或netpoll_send_skb_on_dev的效果吗? -
对不起,我想现在我想要达到的内容更容易理解了。
标签: c linux-kernel network-programming linux-device-driver