我目前编写了一个网络驱动程序,在传输函数中,我想修改套接字缓冲区队列。因此,我需要获得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来解决这个问题。
发布于 2018-02-19 01:24:41
要正确执行此操作,您需要在私有数据结构中设置本地锁:
例如:
struct my_protocol {
spinlock_t lock;
}在dev->open期间使用alloc_netdev()设置它(通常在分配例程中完成),然后您可以使用netdev_priv访问该结构并保持您的锁。
https://stackoverflow.com/questions/48852778
复制相似问题