skb_queue_head_init/skb_queue_head/skb_queue_tail/skb_dequeue/skb_dequeue_tail/skb_queue_purge/skb_queue_walk

skb_queue_head_init: init one list for skb

static inline void skb_queue_head_init(struct sk_buff_head *list)
{                                                                                                                                                     
    spin_lock_init(&list->lock);
    list->prev = list->next = (struct sk_buff *)list;
    list->qlen = 0; 
}

skb_queue_head : 加一个skb到链表头

void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)                                                                                 
{
    unsigned long flags;

    spin_lock_irqsave(&list->lock, flags);
    __skb_queue_head(list, newsk);
    spin_unlock_irqrestore(&list->lock, flags);
}
static inline void __skb_queue_head(struct sk_buff_head *list,
                    struct sk_buff *newsk)
{
    struct sk_buff *prev, *next;

    newsk->list = list;
    list->qlen++;
    prev = (struct sk_buff *)list;
    next = prev->next;
    newsk->next = next;
    newsk->prev = prev;
    next->prev  = prev->next = newsk;
}

skb_queue_tail: 加一个skb到链表尾

void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
{                                                                                                                                                     
    unsigned long flags;

    spin_lock_irqsave(&list->lock, flags);
    __skb_queue_tail(list, newsk);
    spin_unlock_irqrestore(&list->lock, flags);
}
static inline void __skb_queue_tail(struct sk_buff_head *list,                                                                                        
                   struct sk_buff *newsk)
{
    struct sk_buff *prev, *next;
    
    newsk->list = list;
    list->qlen++;
    next = (struct sk_buff *)list;
    prev = next->prev;
    newsk->next = next;
    newsk->prev = prev;
    next->prev  = prev->next = newsk;
}

skb_dequeue : 将一个skb queue 从链表头去掉

struct sk_buff *skb_dequeue(struct sk_buff_head *list)
{                                                                                                                                                     
    unsigned long flags;
    struct sk_buff *result;

    spin_lock_irqsave(&list->lock, flags);
    result = __skb_dequeue(list);
    spin_unlock_irqrestore(&list->lock, flags);
    return result;
}
static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
{
    struct sk_buff *next, *prev, *result;

    prev = (struct sk_buff *) list;
    next = prev->next;
    result = NULL;
    if (next != prev) {
        result       = next;
        next         = next->next;
        list->qlen--;
        next->prev   = prev;
        prev->next   = next;
        result->next = result->prev = NULL;
        result->list = NULL;
    }
    return result;
}

skb_dequeue_tail : 将一个skb queue 从链表尾部去掉。

struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
{                                                                                                                                                     
    unsigned long flags;
    struct sk_buff *result;

    spin_lock_irqsave(&list->lock, flags);
    result = __skb_dequeue_tail(list);
    spin_unlock_irqrestore(&list->lock, flags);
    return result;
}
static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list)
{                                                                                                                                                     
    struct sk_buff *skb = skb_peek_tail(list);
    if (skb)
        __skb_unlink(skb, list);
    return skb;
} 
static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_)
{                                                                                                                                                     
    struct sk_buff *list = ((struct sk_buff *)list_)->prev;
    if (list == (struct sk_buff *)list_)
        list = NULL;
    return list;
}
static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
{                                                                                                                                                     
    struct sk_buff *next, *prev;

    list->qlen--;
    next       = skb->next;
    prev       = skb->prev;
    skb->next  = skb->prev = NULL;
    skb->list  = NULL;
    next->prev = prev;
    prev->next = next;
}

skb_queue_purge : 将某个链表清空

void skb_queue_purge(struct sk_buff_head *list)
{                                                                                                                                                     
    struct sk_buff *skb;
    while ((skb = skb_dequeue(list)) != NULL)
        kfree_skb(skb);
}

skb_queue_walk : 遍历链表

#define skb_queue_walk(queue, skb) \                                                                                                                  
        for (skb = (queue)->next, prefetch(skb->next);  \
             (skb != (struct sk_buff *)(queue));    \
             skb = skb->next, prefetch(skb->next))
posted @ 2018-05-02 10:38  johnson.c  阅读(2027)  评论(0编辑  收藏  举报