I currently write a network driver, and in the transmit function I want to modify the socket buffer queue. Therefore I need to get the lock of sk_buff_head, but the link to the head from a socket buffer was removed years ago.
How can I access sk_buff_head from ndo_start_xmit(struct sk_buff *skb, net_device *dev)?
I am using current linux kernel 4.15.3.
Background
I modify an existing driver for a virtual network device to implement fragmentation which relies on the order of frames, so the second fragment must be sent directly after the first fragment. It works on layer 2 frames.
Therefore I hook up in the start_xmitfunction, simplified it looks like this:
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);
}
So I want to reach that both skbs are sent in exactly this order, there should not be a frame sent in between which passes this driver. This works, when using ping flood mode oder iperf with UDP but sometimes it messes up with iperf using a TCP connection. Then, there are some cases where the order is messed up.
To solve this, I thought I need the "real" queue lock for the skb and so I need sk_buff_head for this.
__dev_queue_xmitornetpoll_send_skb_on_dev? - Michael Foukarakis