/**
* skb_queue_splice - join two skb lists, this is designed for stacks
* @list: the new list to add
* @head: the place to add it in the first list
*/
static inline void skb_queue_splice(const struct sk_buff_head *list,
struct sk_buff_head *head)
{
if (!skb_queue_empty(list)) {
__skb_queue_splice(list, (struct sk_buff *) head, head->next);
head->qlen += list->qlen;
}
}
static inline void __skb_queue_splice(const struct sk_buff_head *list,
struct sk_buff *prev,
struct sk_buff *next)
{
struct sk_buff *first = list->next;
struct sk_buff *last = list->prev;
WRITE_ONCE(first->prev, prev);
WRITE_ONCE(prev->next, first);
WRITE_ONCE(last->next, next);
WRITE_ONCE(next->prev, last);
}
- 首先我们假设有2个skb队列,list和head, 如下(1)所示, 我们要将list拼接合并到head中
- 根据拼接函数的参数, 需要修改的节点拆解开来为list, head和head->next, 如下(2)红色节点
- 进入到实际处理函数, 进一步把list->prev和list->next拆解出来进行拼接合并, 拼接完成后如下图(3)所示, 通过head可以遍历所有节点, 且head->qlen为原来两个队列的qlen之和.
- 这时候list依然指向着之前的节点, 从图中可以看到list也可以遍历整个新队列, 但是list->qlen并没有更新, 同时这时候有head的存在list是已经没有任何作用的了